Documentation for OpenFLUID 2.2.0
CommandLineParser.hpp
Go to the documentation of this file.
1 /*
2 
3  This file is part of OpenFLUID software
4  Copyright(c) 2007, INRA - Montpellier SupAgro
5 
6 
7  == GNU General Public License Usage ==
8 
9  OpenFLUID is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  OpenFLUID is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21 
22 
23  == Other Usage ==
24 
25  Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26  license, and requires a written agreement between You and INRA.
27  Licensees for Other Usage of OpenFLUID may use this file in accordance
28  with the terms contained in the written agreement between You and INRA.
29 
30 */
31 
32 /**
33  @file CommandLineParser.hpp
34 
35  @author Jean-Christophe FABRE <jean-christophe.fabre@inra.fr>
36  @author Dorian GERARDIN <dorian.gerardin@inrae.fr>
37 */
38 
39 
40 #ifndef __OPENFLUID_UTILS_COMMANDLINEPARSER_HPP__
41 #define __OPENFLUID_UTILS_COMMANDLINEPARSER_HPP__
42 
43 
44 #include <map>
45 #include <vector>
46 #include <limits>
47 #include <list>
48 #include <string>
49 #include <ostream>
50 
51 
52 namespace openfluid { namespace utils {
53 
54 
56 {
57  private:
58 
59  std::string m_LongName;
60 
61  std::string m_ShortName;
62 
63  bool m_ValueRequired;
64 
65  std::string m_Value;
66 
67  std::string m_HelpText;
68 
69  bool m_Active;
70 
71 
72  public:
73 
75  m_ValueRequired(false),m_Active(false)
76  { }
77 
78 
79  // =====================================================================
80  // =====================================================================
81 
82 
83  /**
84  Instanciates an option with the given parameters
85  @param[in] LongName The long name of the option
86  @param[in] ShortName The short name of the option
87  @param[in] HelpText The help text associated to the option
88  @param[in] ValueRequired Set to true to require a value with this option (default is false)
89  */
90  CommandLineOption(const std::string& LongName, const std::string& ShortName,
91  const std::string& HelpText, bool ValueRequired = false):
92  m_LongName(LongName),m_ShortName(ShortName), m_ValueRequired(ValueRequired), m_HelpText(HelpText),
93  m_Active(false)
94  { }
95 
96 
97  // =====================================================================
98  // =====================================================================
99 
100 
101  /**
102  Returns the help text of the option
103  @return The help text
104  */
105  std::string getHelpText() const
106  {
107  return m_HelpText;
108  }
109 
110 
111  // =====================================================================
112  // =====================================================================
113 
114 
115  /**
116  Returns the long name of the option (e.g. 'output-dir')
117  @return The long name
118  */
119  std::string getLongName() const
120  {
121  return m_LongName;
122  }
123 
124 
125  // =====================================================================
126  // =====================================================================
127 
128 
129  /**
130  Returns the short name of the option (e.g. 'o')
131  @return The short name
132  */
133  std::string getShortName() const
134  {
135  return m_ShortName;
136  }
137 
138 
139  // =====================================================================
140  // =====================================================================
141 
142 
143  /**
144  Returns the value of the option
145  @return The value
146  */
147  std::string getValue() const
148  {
149  return m_Value;
150  }
151 
152 
153  // =====================================================================
154  // =====================================================================
155 
156 
157  /**
158  Returns the value of the option
159  @return The value
160  */
161  std::string getDetails() const
162  {
163  std::string OptionDetail = "--" + getLongName();
164  if (isValueRequired())
165  {
166  OptionDetail += "=<arg>";
167  }
168 
169  if (!getShortName().empty())
170  {
171  OptionDetail += ", -" + getShortName();
172  if (isValueRequired())
173  {
174  OptionDetail += " <arg>";
175  }
176  }
177  return OptionDetail;
178  }
179 
180 
181  // =====================================================================
182  // =====================================================================
183 
184 
185  /**
186  Tests if the option is active
187  @return true if the option is active
188  */
189  bool isActive() const
190  {
191  return m_Active;
192  }
193 
194 
195  // =====================================================================
196  // =====================================================================
197 
198 
199  /**
200  Tests if the option requires a value
201  @return true if the option requires a value
202  */
203  bool isValueRequired() const
204  {
205  return m_ValueRequired;
206  }
207 
208 
209  // =====================================================================
210  // =====================================================================
211 
212 
213  /**
214  Activates the option with the given value
215  @param[in] Value The value for activation (default is empty)
216  */
217  void activate(const std::string& Value = "")
218  {
219  m_Value = Value;
220 
221  if ((!m_ValueRequired) || (m_ValueRequired && !m_Value.empty()))
222  {
223  m_Active = true;
224  }
225  else
226  {
227  m_Active = false;
228  }
229  }
230 
231 
232  // =====================================================================
233  // =====================================================================
234 
235 
236  /**
237  Resets the option to default (inactive with empty value)
238  */
239  void reset()
240  {
241  m_Active = false;
242  m_Value = "";
243  }
244 
245 };
246 
247 
248 // =====================================================================
249 // =====================================================================
250 
251 
253 {
254  private:
255 
256  std::string m_Name;
257  bool m_Required;
258 
259  public:
260 
261  /**
262  Instanciates an argument with the given parameters
263  @param[in] Name The long name of the option
264  @param[in] Required True if the argument is required (true is default)
265  */
266  CommandLineArg(const std::string& Name, bool Required = true):
267  m_Name(Name), m_Required(Required)
268  { }
269 
270 
271  // =====================================================================
272  // =====================================================================
273 
274 
275  /**
276  Returns the name of the arg
277  @return The name
278  */
279  std::string getName() const
280  {
281  return m_Name;
282  }
283 
284 
285  // =====================================================================
286  // =====================================================================
287 
288 
289  /**
290  Returns if the arg is required
291  @return the required predicate
292  */
293  bool isRequired() const
294  {
295  return m_Required;
296  }
297 
298 };
299 
300 
302 {
303  private:
304 
305  std::string m_Name;
306 
307  std::string m_HelpText;
308 
309  std::string m_LongHelpText;
310 
311  std::map<std::string,CommandLineOption> m_Options;
312 
313  std::map<std::string,CommandLineOption*> m_ShortOptions;
314 
315  std::vector<CommandLineOption> m_OptionsOrdered;
316 
317  std::vector<CommandLineArg> m_Args;
318 
319 
320  public:
321 
323  { }
324 
325 
326  // =====================================================================
327  // =====================================================================
328 
329 
330  /**
331  Instanciates a command with the given parameters
332  @param[in] Name The long name of the command
333  @param[in] HelpText The help text associated to the command
334  @param[in] LongHelpText The long help text associated to the command
335  */
336  CommandLineCommand(const std::string& Name, const std::string& HelpText, const std::string& LongHelpText = ""):
337  m_Name(Name), m_HelpText(HelpText)
338  {
339  m_LongHelpText = LongHelpText.empty() ? HelpText : LongHelpText;
340  }
341 
342 
343  // =====================================================================
344  // =====================================================================
345 
346 
347  /**
348  Returns the help text of the command
349  @return The help text
350  */
351  std::string getHelpText() const
352  {
353  return m_HelpText;
354  }
355 
356 
357  // =====================================================================
358  // =====================================================================
359 
360 
361  /**
362  Returns the help text of the command
363  @return The help text
364  */
365  std::string getLongHelpText() const
366  {
367  return m_LongHelpText;
368  }
369 
370 
371  // =====================================================================
372  // =====================================================================
373 
374 
375  /**
376  Returns the name of the command
377  @return The name (e.g. "search")
378  */
379  std::string getName() const
380  {
381  return m_Name;
382  }
383 
384 
385  // =====================================================================
386  // =====================================================================
387 
388 
389  /**
390  Returns the options registered for the command
391  @return The options
392  */
393  const std::map<std::string,CommandLineOption>& options()
394  {
395  return m_Options;
396  }
397 
398 
399  // =====================================================================
400  // =====================================================================
401 
402 
403  /**
404  Returns the options (ordered by addition) registered for the command
405  @return The options
406  */
407  const std::vector<CommandLineOption>& optionsOrdered()
408  {
409  return m_OptionsOrdered;
410  }
411 
412 
413  // =====================================================================
414  // =====================================================================
415 
416 
417  /**
418  Adds an option to the command
419  @param[in] Option The option to add
420  */
421  void addOption(const CommandLineOption& Option)
422  {
423  m_Options[Option.getLongName()] = Option;
424 
425  m_OptionsOrdered.push_back(Option);
426 
427  if (!Option.getShortName().empty())
428  {
429  m_ShortOptions[Option.getShortName()] = &m_Options[Option.getLongName()];
430  }
431  }
432 
433 
434  // =====================================================================
435  // =====================================================================
436 
437 
438  /**
439  Adds many options to the command
440  @param[in] Options The option list to add
441  */
442  void addOptions(const std::vector<CommandLineOption>& Options)
443  {
444  for (const auto& Opt : Options)
445  {
446  addOption(Opt);
447  }
448  }
449 
450 
451  // =====================================================================
452  // =====================================================================
453 
454 
455  /**
456  Activates the given option with the given value
457  @param[in] LongName The long name of the option
458  @param[in] Value The value for activation (default is empty)
459  */
460  bool activateOption(const std::string& LongName, const std::string& Value = "")
461  {
462  auto it = m_Options.find(LongName);
463 
464  if (it == m_Options.end())
465  {
466  return false;
467  }
468 
469  (*it).second.activate(Value);
470  return (*it).second.isActive();
471  }
472 
473 
474  // =====================================================================
475  // =====================================================================
476 
477 
478  /**
479  Returns the long name of an option from its short name
480  @param[in] ShortName The requested short name for the option
481  @return The long name
482  */
483  std::string getOptionNameFromShortName(const std::string& ShortName) const
484  {
485  auto it = m_ShortOptions.find(ShortName);
486 
487  if (it == m_ShortOptions.end())
488  {
489  return "";
490  }
491 
492  return (*it).second->getLongName();
493  }
494 
495 
496  // =====================================================================
497  // =====================================================================
498 
499 
500  /**
501  Tests if an option exists for the command
502  @param[in] LongName The long name for the searched option
503  @return true if the option exists
504  */
505  bool isOptionExists(const std::string& LongName) const
506  {
507  return (m_Options.find(LongName) != m_Options.end());
508  }
509 
510 
511  // =====================================================================
512  // =====================================================================
513 
514 
515  /**
516  Tests if an option requires a value
517  @param[in] LongName The long name for the searched option
518  @return true if the option requires a value
519  */
520  bool isOptionRequiresValue(const std::string& LongName) const
521  {
522  auto it = m_Options.find(LongName);
523 
524  if (it == m_Options.end())
525  {
526  return false;
527  }
528 
529  return (*it).second.isValueRequired();
530  }
531 
532 
533  // =====================================================================
534  // =====================================================================
535 
536 
537  /**
538  Tests if an option is active
539  @param[in] LongName The long name for the searched option
540  @return true if the option is active
541  */
542  bool isOptionActive(const std::string& LongName) const
543  {
544  auto it = m_Options.find(LongName);
545 
546  return (it != m_Options.end() && (*it).second.isActive());
547  }
548 
549 
550  // =====================================================================
551  // =====================================================================
552 
553 
554  /**
555  Returns the value given for an option
556  @param[in] LongName The long name for the option
557  @return the value for the option
558  */
559  std::string getOptionValue(const std::string& LongName) const
560  {
561  auto it = m_Options.find(LongName);
562 
563  if (it == m_Options.end())
564  {
565  return "";
566  }
567 
568  return ((*it).second.getValue());
569  }
570 
571 
572  // =====================================================================
573  // =====================================================================
574 
575 
576  /**
577  Resets all options to default (inactive with empty value)
578  */
579  void reset()
580  {
581  for (auto& Opt : m_Options)
582  {
583  Opt.second.reset();
584  }
585  }
586 
587 
588  // =====================================================================
589  // =====================================================================
590 
591 
592  /**
593  Adds an argument to the command
594  @param[in] Arg The argument to add
595  @param[in] Required True if the arg is required
596  */
597  void addArg(const CommandLineArg& Arg)
598  {
599  m_Args.push_back(Arg);
600  }
601 
602 
603  // =====================================================================
604  // =====================================================================
605 
606 
607  /**
608  Adds many args to the command
609  @param[in] Arg The argument list to add
610  */
611  void addArgs(const std::vector<CommandLineArg>& Args)
612  {
613  for (const auto& Arg : Args)
614  {
615  addArg(Arg);
616  }
617  }
618 
619 
620  // =====================================================================
621  // =====================================================================
622 
623 
624  /**
625  Returns the args registered for the command
626  @return The args
627  */
628  const std::vector<CommandLineArg>& args()
629  {
630  return m_Args;
631  }
632 
633 };
634 
635 
636 // =====================================================================
637 // =====================================================================
638 
639 
640 // OpenFLUID:stylecheck:!incs
641 
642 /**
643  @brief Class for management of command line arguments.
644 
645  This class allows to manage the command line arguments as commands, options and extra arguments.
646 
647  The example below is for a command line program with two commands ('run' and 'search') and associated options
648 @snippet misc/main.cpp cmdlineparser
649 */
651 {
652  protected:
653 
654  std::string m_ProgramName;
655 
656  std::string m_HelpText;
657 
658  std::map<std::string,CommandLineCommand> m_Commands;
659 
660  std::vector<CommandLineCommand> m_CommandsOrdered;
661 
662  std::string m_ActiveCommand;
663 
664  const std::string m_AvailableCommandsText = "Available commands:";
665 
666 
667  // =====================================================================
668  // =====================================================================
669 
670 
672  {
673  int LargestCommandLength = std::numeric_limits<int>::min();
674  for (auto& Cmd : m_Commands)
675  {
676  LargestCommandLength = std::max(LargestCommandLength, (int)Cmd.first.size());
677  }
678 
679  return LargestCommandLength;
680  }
681 
682 
683  // =====================================================================
684  // =====================================================================
685 
686 
688  {
689  std::map<std::string,CommandLineOption> AllOptions(m_Commands[m_ActiveCommand].options());
690  CommandLineOption HelpOption = getHelpOption();
691  AllOptions.insert({HelpOption.getShortName(), HelpOption});
692 
693  int LargestOptionLength = std::numeric_limits<int>::min();
694  for (auto& Opt : AllOptions)
695  {
696  LargestOptionLength = std::max(LargestOptionLength, (int)Opt.second.getDetails().size());
697  }
698 
699  return LargestOptionLength;
700  }
701 
702 
703  // =====================================================================
704  // =====================================================================
705 
706 
707  std::string getCustomIndent(int CommandLength, int LargestCommandLength, std::string minimalSpace = " ")
708  {
709  int Delta = LargestCommandLength - CommandLength;
710  if (Delta > 0)
711  {
712  minimalSpace.append(Delta, ' ');
713  }
714  return minimalSpace;
715  }
716 
717 
718  // =====================================================================
719  // =====================================================================
720 
721 
723  {
724  return CommandLineOption("help","h","display this help message");
725  }
726 
727 
728  // =====================================================================
729  // =====================================================================
730 
731 
732  void displayFormattedData(std::ostream& OutStm, std::string Title, std::string HelpText, int LargestTextLength)
733  {
734  OutStm << " " << Title << getCustomIndent(Title.size(), LargestTextLength) << HelpText << "\n";
735  }
736 
737 
738  // =====================================================================
739  // =====================================================================
740 
741 
742  void displayOptions(std::ostream& OutStm, CommandLineOption HelpOption, int LargestTextLength)
743  {
744  OutStm << "\nAvailable options:\n";
745 
746  displayFormattedData(OutStm, HelpOption.getDetails(), HelpOption.getHelpText(), LargestTextLength);
747 
748  if(m_UseCustomOrder)
749  {
750  for (auto& Opt : m_Commands[m_ActiveCommand].optionsOrdered())
751  {
752  displayFormattedData(OutStm, Opt.getDetails(), Opt.getHelpText(), LargestTextLength);
753  }
754  }
755  else
756  {
757  for (auto& Opt : m_Commands[m_ActiveCommand].options())
758  {
759  displayFormattedData(OutStm, Opt.second.getDetails(), Opt.second.getHelpText(), LargestTextLength);
760  }
761  }
762  }
763 
764 
765  // =====================================================================
766  // =====================================================================
767 
768 
769  std::string getArgsDisplay()
770  {
771  std::string Args = "";
772  for (auto& Arg : m_Commands[m_ActiveCommand].args())
773  {
774  if(Arg.isRequired())
775  {
776  Args += "<" + Arg.getName() + "> ";
777  }
778  else
779  {
780  Args += "[<" + Arg.getName() + ">] ";
781  }
782  }
783 
784  return Args;
785  }
786 
787 
788  // =====================================================================
789  // =====================================================================
790 
791 
792  void displayUsageMessage(std::ostream& OutStm)
793  {
794  std::string CmdName = m_ActiveCommand;
795 
796  if (CmdName.empty())
797  {
798  CmdName = "[<command>]";
799  }
800 
801  OutStm << "Usage : " << m_ProgramName << " " << CmdName << " [<options>] " << getArgsDisplay() << "\n";
802  }
803 
804 
805  private:
806 
807  std::vector<std::string> m_ExtraArgs;
808 
809  std::vector<std::string> m_ThirdPartyArgs;
810 
811  std::string m_ParsingMessage;
812 
813  bool m_HelpAsked;
814 
815  bool m_UseCustomOrder;
816 
817  public:
818 
820  m_HelpAsked(false), m_UseCustomOrder(false)
821  {
823  }
824 
825 
826  // =====================================================================
827  // =====================================================================
828 
829 
830  /**
831  Instanciates a command line parser with the given parameters
832  @param[in] ProgramName The name of the programn
833  @param[in] HelpText The help text associated to the option
834  @param[in] UseCustomOrder Enables custom order in the display
835  */
836  CommandLineParser(const std::string& ProgramName, const std::string& HelpText, bool UseCustomOrder = false) :
837  m_ProgramName(ProgramName), m_HelpText(HelpText), m_HelpAsked(false), m_UseCustomOrder(UseCustomOrder)
838  {
840  }
841 
842 
843  // =====================================================================
844  // =====================================================================
845 
846 
847  /**
848  Returns the extra arguments given to the command
849  @return a vector of arguments
850  */
851  const std::vector<std::string>& extraArgs() const
852  {
853  return m_ExtraArgs;
854  }
855 
856 
857  // =====================================================================
858  // =====================================================================
859 
860 
861  /**
862  Returns the third party arguments given to the command,
863  mainly used to pass arguments to a third party program
864  @return a vector of arguments
865  */
866  const std::vector<std::string>& thirdPartyArgs() const
867  {
868  return m_ThirdPartyArgs;
869  }
870 
871 
872  // =====================================================================
873  // =====================================================================
874 
875 
876  /**
877  Returns the help text of the parser
878  @return The help text
879  */
880  std::string getHelpText() const
881  {
882  return m_HelpText;
883  }
884 
885 
886  // =====================================================================
887  // =====================================================================
888 
889 
890  /**
891  Returns the program name
892  @return The program name
893  */
894  std::string getProgramName() const
895  {
896  return m_ProgramName;
897  }
898 
899 
900  // =====================================================================
901  // =====================================================================
902 
903 
904  /**
905  Returns the message given by the parsing process in case of error(s)
906  @return The message
907  */
908  std::string getParsingMessage() const
909  {
910  return m_ParsingMessage;
911  }
912 
913 
914  // =====================================================================
915  // =====================================================================
916 
917 
918  /**
919  Returns the active command name
920  @return The active command name
921  */
922  std::string getActiveCommand() const
923  {
924  return m_ActiveCommand;
925  }
926 
927 
928  // =====================================================================
929  // =====================================================================
930 
931 
932  /**
933  Returns the command corresponding to the given name
934  @param[in] Name the name of the command
935  @return The command object
936  */
937  const CommandLineCommand& command(const std::string& Name) const
938  {
939  return m_Commands.at(Name);
940  }
941 
942 
943  // =====================================================================
944  // =====================================================================
945 
946 
947  /**
948  Adds a command to the parser
949  @param[in] Command The command to add
950  */
951  void addCommand(const CommandLineCommand& Command)
952  {
953  m_Commands[Command.getName()] = Command;
954  m_CommandsOrdered.push_back(Command);
955  }
956 
957 
958  // =====================================================================
959  // =====================================================================
960 
961 
962  /**
963  Adds a global option to the parser
964  @param[in] Option The option to add
965  */
966  void addOption(const CommandLineOption& Option)
967  {
968  m_Commands[""].addOption(Option);
969  }
970 
971 
972  // =====================================================================
973  // =====================================================================
974 
975 
976  /**
977  Parses a list of string arguments
978  @param[in] ArgValues The lists of arguments to parse
979  @return true if the parsing is succesful, false otherwise
980  */
981  bool parse(std::list<std::string> ArgValues)
982  {
983  reset();
984 
985  while (!ArgValues.empty())
986  {
987  std::string Arg = ArgValues.front();
988  ArgValues.pop_front();
989 
990  if (Arg == "---")
991  {
992  m_ThirdPartyArgs = { std::make_move_iterator(std::begin(ArgValues)),
993  std::make_move_iterator(std::end(ArgValues)) };
994  return true;
995  }
996 
997  if (Arg[0] != '-')
998  {
999  // arg not an option
1000  if (m_ActiveCommand.empty())
1001  {
1002  m_ActiveCommand = Arg;
1003  }
1004  else
1005  {
1006  m_ExtraArgs.push_back(Arg);
1007  }
1008  }
1009  else
1010  {
1011  // arg is an option
1012 
1013  // check if the command exists
1014  auto it = m_Commands.find(m_ActiveCommand);
1015  if (it == m_Commands.end())
1016  {
1017  m_ParsingMessage = "unknown \""+ m_ActiveCommand + "\" command";
1018  return false;
1019  }
1020 
1021  if (Arg == "-h" || Arg == "--help")
1022  {
1023  m_HelpAsked = true;
1024  }
1025  else if (Arg.size() < 2)
1026  {
1027  m_ParsingMessage = "wrong format for option \"" + Arg + "\"";
1028  return false;
1029  }
1030  else
1031  {
1032  std::string LongOptName;
1033  std::string OptValue;
1034  bool IsFromShort = false;
1035 
1036  if (Arg[1] != '-')
1037  {
1038  if (Arg.size() != 2)
1039  {
1040  m_ParsingMessage = "wrong format for short option \"" + Arg + "\"";
1041  return false;
1042  }
1043 
1044  // short option
1045  LongOptName = m_Commands[m_ActiveCommand].getOptionNameFromShortName(Arg.substr(1,1));
1046  IsFromShort = true;
1047  }
1048  else
1049  {
1050  // long option
1051  std::string TmpName = Arg.substr(2,Arg.size()-2);
1052 
1053  std::string::size_type EqualPos = TmpName.find("=");
1054 
1055  if (EqualPos != std::string::npos)
1056  {
1057  LongOptName = TmpName.substr(0,EqualPos);
1058  OptValue = TmpName.substr(EqualPos+1,TmpName.size()-EqualPos-1);
1059  }
1060  else
1061  {
1062  LongOptName = TmpName;
1063  }
1064  }
1065 
1066  if (!m_Commands[m_ActiveCommand].isOptionExists(LongOptName))
1067  {
1068  // unknown option
1069  m_ParsingMessage = "unknown option \"" + Arg + "\"";
1070  if (!m_ActiveCommand.empty())
1071  {
1072  m_ParsingMessage += " for command \"" + m_ActiveCommand + "\"";
1073  }
1074  return false;
1075  }
1076 
1077  if (m_Commands[m_ActiveCommand].isOptionRequiresValue(LongOptName))
1078  {
1079  if (IsFromShort && !ArgValues.empty())
1080  {
1081  OptValue = ArgValues.front();
1082  ArgValues.pop_front();
1083  }
1084 
1085  if (OptValue.empty())
1086  {
1087  m_ParsingMessage = "missing value for option \"" + Arg + "\"";
1088  return false;
1089  }
1090  }
1091 
1092  if (!m_Commands[m_ActiveCommand].activateOption(LongOptName,OptValue))
1093  {
1094  // wrong option format
1095  m_ParsingMessage = "unknown error for option \"" + Arg + "\"";
1096  return false;
1097  }
1098  }
1099  }
1100  }
1101  return true;
1102  }
1103 
1104 
1105  // =====================================================================
1106  // =====================================================================
1107 
1108 
1109  /**
1110  Parses arguments from the standard parameters `(int argc,char** argv)` given through the main function
1111  @param[in] ArgC The number of arguments
1112  @param[in] ArgV The array of arguments
1113  @return true if the parsing is succesful, false otherwise
1114  */
1115  bool parse(int ArgC, char **ArgV)
1116  {
1117  std::list<std::string> ArgValues;
1118 
1119  for (int i=1; i< ArgC; i++)
1120  {
1121  ArgValues.push_back(std::string(ArgV[i]));
1122  }
1123 
1124  return parse(ArgValues);
1125  }
1126 
1127 
1128  // =====================================================================
1129  // =====================================================================
1130 
1131 
1132  /**
1133  Resets the parser to default (no active command, no extra arguments, no option activated)
1134  */
1135  void reset()
1136  {
1137  m_ActiveCommand.clear();
1138  m_ParsingMessage.clear();
1139  m_ExtraArgs.clear();
1140  m_ThirdPartyArgs.clear();
1141 
1142  for (auto& Cmd : m_Commands)
1143  {
1144  Cmd.second.reset();
1145  }
1146  }
1147 
1148 
1149  // =====================================================================
1150  // =====================================================================
1151 
1152 
1153  /**
1154  Tests if the help is asked
1155  @return true if the help is asked
1156  */
1158  {
1159  return m_HelpAsked;
1160  }
1161 
1162 
1163  // =====================================================================
1164  // =====================================================================
1165 
1166 
1167  /**
1168  Prints the help text
1169  @param[in] OutStm The stream where the help text is printed (e.g. std::cout)
1170  */
1171  void printHelp(std::ostream& OutStm)
1172  {
1173  displayUsageMessage(OutStm);
1174 
1175  int LargestCommandTextLength = getLargestCommandLength();
1176  int LargestOptionTextLength = getLargestOptionLength();
1177 
1178  if (m_ActiveCommand.empty())
1179  {
1180  OutStm << "\n" << m_AvailableCommandsText << "\n";
1181 
1182  if(m_UseCustomOrder)
1183  {
1184  for (const auto& Cmd : m_CommandsOrdered)
1185  {
1186  if (!Cmd.getName().empty())
1187  {
1188  displayFormattedData(OutStm, Cmd.getName(), Cmd.getHelpText(), LargestCommandTextLength);
1189  }
1190  }
1191  }
1192  else
1193  {
1194  for (const auto& Cmd : m_Commands)
1195  {
1196  if (!Cmd.first.empty())
1197  {
1198  displayFormattedData(OutStm, Cmd.first, Cmd.second.getHelpText(), LargestCommandTextLength);
1199  }
1200  }
1201  }
1202  }
1203 
1204  if (!m_Commands[m_ActiveCommand].getLongHelpText().empty())
1205  {
1206  OutStm << "\n" << m_Commands[m_ActiveCommand].getLongHelpText() << "\n";
1207  }
1208 
1209  displayOptions(OutStm, getHelpOption(), LargestOptionTextLength);
1210  }
1211 
1212 
1213  // =====================================================================
1214  // =====================================================================
1215 
1216 
1217  /**
1218  Prints the state of the parser
1219  @param[in] OutStm The stream where the help text is printed (e.g. std::cout)
1220  */
1221  void printState(std::ostream& OutStm)
1222  {
1223  for (auto& Cmd : m_Commands)
1224  {
1225  if (!Cmd.first.empty())
1226  {
1227  if (Cmd.first == m_ActiveCommand)
1228  {
1229  OutStm << "+";
1230  }
1231  else
1232  {
1233  OutStm << "-";
1234  }
1235 
1236  OutStm << " " << Cmd.first << " : " << Cmd.second.getHelpText() << "\n";
1237 
1238  for (auto& Opt : Cmd.second.options())
1239  {
1240  OutStm << " ";
1241 
1242  if (Opt.second.isActive())
1243  {
1244  OutStm << "+";
1245  }
1246  else
1247  {
1248  OutStm << "-";
1249  }
1250  OutStm << " " << Opt.first;
1251 
1252  if (!Opt.second.getShortName().empty())
1253  {
1254  OutStm << "," << Opt.second.getShortName();
1255  }
1256 
1257  if (Opt.second.isValueRequired())
1258  {
1259  OutStm << "[" << Opt.second.getValue() << "]";
1260  }
1261 
1262  OutStm << " : " << Opt.second.getHelpText() << "\n";
1263  }
1264  }
1265  }
1266 
1267 
1268  if (!m_ExtraArgs.empty())
1269  {
1270  OutStm << "Extra arguments :";
1271 
1272  for (auto& Arg : m_ExtraArgs)
1273  {
1274  OutStm << " " << Arg;
1275  }
1276 
1277  OutStm << "\n";
1278  }
1279 
1280  }
1281 
1282 };
1283 
1284 
1285 } }
1286 
1287 
1288 #endif /* __OPENFLUID_UTILS_COMMANDLINEPARSER_HPP__ */
Definition: CommandLineParser.hpp:253
std::string getName() const
Definition: CommandLineParser.hpp:279
CommandLineArg(const std::string &Name, bool Required=true)
Definition: CommandLineParser.hpp:266
bool isRequired() const
Definition: CommandLineParser.hpp:293
Definition: CommandLineParser.hpp:302
bool isOptionActive(const std::string &LongName) const
Definition: CommandLineParser.hpp:542
const std::vector< CommandLineArg > & args()
Definition: CommandLineParser.hpp:628
const std::map< std::string, CommandLineOption > & options()
Definition: CommandLineParser.hpp:393
void addArg(const CommandLineArg &Arg)
Definition: CommandLineParser.hpp:597
bool isOptionExists(const std::string &LongName) const
Definition: CommandLineParser.hpp:505
std::string getName() const
Definition: CommandLineParser.hpp:379
std::string getOptionValue(const std::string &LongName) const
Definition: CommandLineParser.hpp:559
void addOption(const CommandLineOption &Option)
Definition: CommandLineParser.hpp:421
CommandLineCommand(const std::string &Name, const std::string &HelpText, const std::string &LongHelpText="")
Definition: CommandLineParser.hpp:336
const std::vector< CommandLineOption > & optionsOrdered()
Definition: CommandLineParser.hpp:407
CommandLineCommand()
Definition: CommandLineParser.hpp:322
std::string getHelpText() const
Definition: CommandLineParser.hpp:351
void reset()
Definition: CommandLineParser.hpp:579
std::string getOptionNameFromShortName(const std::string &ShortName) const
Definition: CommandLineParser.hpp:483
void addArgs(const std::vector< CommandLineArg > &Args)
Definition: CommandLineParser.hpp:611
bool isOptionRequiresValue(const std::string &LongName) const
Definition: CommandLineParser.hpp:520
void addOptions(const std::vector< CommandLineOption > &Options)
Definition: CommandLineParser.hpp:442
bool activateOption(const std::string &LongName, const std::string &Value="")
Definition: CommandLineParser.hpp:460
std::string getLongHelpText() const
Definition: CommandLineParser.hpp:365
Definition: CommandLineParser.hpp:56
std::string getValue() const
Definition: CommandLineParser.hpp:147
CommandLineOption(const std::string &LongName, const std::string &ShortName, const std::string &HelpText, bool ValueRequired=false)
Definition: CommandLineParser.hpp:90
void reset()
Definition: CommandLineParser.hpp:239
std::string getDetails() const
Definition: CommandLineParser.hpp:161
std::string getLongName() const
Definition: CommandLineParser.hpp:119
void activate(const std::string &Value="")
Definition: CommandLineParser.hpp:217
std::string getHelpText() const
Definition: CommandLineParser.hpp:105
bool isValueRequired() const
Definition: CommandLineParser.hpp:203
bool isActive() const
Definition: CommandLineParser.hpp:189
std::string getShortName() const
Definition: CommandLineParser.hpp:133
CommandLineOption()
Definition: CommandLineParser.hpp:74
Class for management of command line arguments.
Definition: CommandLineParser.hpp:651
void reset()
Definition: CommandLineParser.hpp:1135
std::string m_ProgramName
Definition: CommandLineParser.hpp:654
bool parse(std::list< std::string > ArgValues)
Definition: CommandLineParser.hpp:981
const std::string m_AvailableCommandsText
Definition: CommandLineParser.hpp:664
CommandLineParser(const std::string &ProgramName, const std::string &HelpText, bool UseCustomOrder=false)
Definition: CommandLineParser.hpp:836
int getLargestCommandLength()
Definition: CommandLineParser.hpp:671
void displayUsageMessage(std::ostream &OutStm)
Definition: CommandLineParser.hpp:792
std::string m_HelpText
Definition: CommandLineParser.hpp:656
std::string getActiveCommand() const
Definition: CommandLineParser.hpp:922
std::vector< CommandLineCommand > m_CommandsOrdered
Definition: CommandLineParser.hpp:660
void displayFormattedData(std::ostream &OutStm, std::string Title, std::string HelpText, int LargestTextLength)
Definition: CommandLineParser.hpp:732
std::string getHelpText() const
Definition: CommandLineParser.hpp:880
bool parse(int ArgC, char **ArgV)
Definition: CommandLineParser.hpp:1115
bool isHelpAsked()
Definition: CommandLineParser.hpp:1157
std::map< std::string, CommandLineCommand > m_Commands
Definition: CommandLineParser.hpp:658
const std::vector< std::string > & thirdPartyArgs() const
Definition: CommandLineParser.hpp:866
CommandLineOption getHelpOption()
Definition: CommandLineParser.hpp:722
void printHelp(std::ostream &OutStm)
Definition: CommandLineParser.hpp:1171
std::string getCustomIndent(int CommandLength, int LargestCommandLength, std::string minimalSpace=" ")
Definition: CommandLineParser.hpp:707
std::string getArgsDisplay()
Definition: CommandLineParser.hpp:769
void addOption(const CommandLineOption &Option)
Definition: CommandLineParser.hpp:966
void addCommand(const CommandLineCommand &Command)
Definition: CommandLineParser.hpp:951
int getLargestOptionLength()
Definition: CommandLineParser.hpp:687
void printState(std::ostream &OutStm)
Definition: CommandLineParser.hpp:1221
void displayOptions(std::ostream &OutStm, CommandLineOption HelpOption, int LargestTextLength)
Definition: CommandLineParser.hpp:742
std::string getParsingMessage() const
Definition: CommandLineParser.hpp:908
std::string m_ActiveCommand
Definition: CommandLineParser.hpp:662
const std::vector< std::string > & extraArgs() const
Definition: CommandLineParser.hpp:851
CommandLineParser()
Definition: CommandLineParser.hpp:819
std::string getProgramName() const
Definition: CommandLineParser.hpp:894
const CommandLineCommand & command(const std::string &Name) const
Definition: CommandLineParser.hpp:937
Definition: ApplicationException.hpp:47