00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #if !defined(_XRB_COMMANDLINEPARSER_HPP_)
00012 #define _XRB_COMMANDLINEPARSER_HPP_
00013
00014 #include "xrb.hpp"
00015
00016 #include <iostream>
00017 #include <string>
00018
00019 namespace Xrb
00020 {
00021
00022 struct CommandLineOption;
00023
00024 class CommandLineParser
00025 {
00026 public:
00027
00028 typedef void (CommandLineParser::*HandlerMethodWithArgument)(std::string const &);
00029 typedef void (CommandLineParser::*HandlerMethodWithoutArgument)();
00030
00031 template <typename CommandLineParserSubclass>
00032 CommandLineParser (
00033 void (CommandLineParserSubclass::*non_option_argument_handler_method)(std::string const &),
00034 CommandLineOption const *option,
00035 Uint32 option_count,
00036 std::string const &executable_path,
00037 std::string const &program_description,
00038 std::string const &usage_message)
00039 :
00040 m_non_option_argument_handler_method(static_cast<HandlerMethodWithArgument>(non_option_argument_handler_method)),
00041 m_option(option),
00042 m_option_count(option_count),
00043 m_executable_path(executable_path),
00044 m_program_description(program_description),
00045 m_usage_message(usage_message),
00046 m_parse_succeeded(true)
00047 {
00048 ASSERT0(m_non_option_argument_handler_method != NULL);
00049 ASSERT0(m_option != NULL);
00050 ASSERT0(m_option_count > 0);
00051 ASSERT1(!m_executable_path.empty());
00052
00053 PerformOptionConsistencyCheck();
00054 }
00055 virtual ~CommandLineParser () = 0;
00056
00057 inline bool ParseSucceeded () const { return m_parse_succeeded; }
00058
00059 void Parse (Sint32 argc, char const *const *argv);
00060 void PrintHelpMessage (std::ostream &stream) const;
00061
00062 private:
00063
00064 static bool IsAControlOption (CommandLineOption const &option);
00065 static bool IsAShortNameCollision (CommandLineOption const &option_0, CommandLineOption const &option_1);
00066 static bool IsALongNameCollision (CommandLineOption const &option_0, CommandLineOption const &option_1);
00067
00068 void PerformOptionConsistencyCheck () const;
00069
00070
00071 bool HandleShortNameOption (char const *arg, char const *next_arg);
00072
00073 bool HandleLongNameOption (char const *arg, char const *next_arg);
00074
00075 CommandLineOption const *FindOptionByShortName (char short_name) const;
00076 CommandLineOption const *FindOptionByLongName (char const *long_name) const;
00077
00078 HandlerMethodWithArgument const m_non_option_argument_handler_method;
00079 CommandLineOption const *const m_option;
00080 Uint32 const m_option_count;
00081 std::string const m_executable_path;
00082 std::string const m_program_description;
00083 std::string const m_usage_message;
00084 bool m_parse_succeeded;
00085 };
00086
00087 struct CommandLineOption
00088 {
00089 public:
00090
00091 CommandLineOption (std::string const &header_text)
00092 :
00093 m_short_name('\n'),
00094 m_long_name(),
00095 m_requires_an_argument(false),
00096 m_handler_method_with_argument(NULL),
00097 m_handler_method_without_argument(NULL),
00098 m_description(header_text)
00099 { }
00100 template <typename CommandLineParserSubclass>
00101 CommandLineOption (
00102 char short_name,
00103 void (CommandLineParserSubclass::*handler_method_with_argument)(std::string const &),
00104 std::string const &description)
00105 :
00106 m_short_name(short_name),
00107 m_long_name(),
00108 m_requires_an_argument(true),
00109 m_handler_method_with_argument(static_cast<HandlerMethodWithArgument>(handler_method_with_argument)),
00110 m_handler_method_without_argument(NULL),
00111 m_description(description)
00112 { }
00113 template <typename CommandLineParserSubclass>
00114 CommandLineOption (
00115 std::string const &long_name,
00116 void (CommandLineParserSubclass::*handler_method_with_argument)(std::string const &),
00117 std::string const &description)
00118 :
00119 m_short_name('\0'),
00120 m_long_name(long_name),
00121 m_requires_an_argument(true),
00122 m_handler_method_with_argument(static_cast<HandlerMethodWithArgument>(handler_method_with_argument)),
00123 m_handler_method_without_argument(NULL),
00124 m_description(description)
00125 { }
00126 template <typename CommandLineParserSubclass>
00127 CommandLineOption (
00128 char short_name,
00129 std::string const &long_name,
00130 void (CommandLineParserSubclass::*handler_method_with_argument)(std::string const &),
00131 std::string const &description)
00132 :
00133 m_short_name(short_name),
00134 m_long_name(long_name),
00135 m_requires_an_argument(true),
00136 m_handler_method_with_argument(static_cast<HandlerMethodWithArgument>(handler_method_with_argument)),
00137 m_handler_method_without_argument(NULL),
00138 m_description(description)
00139 { }
00140 template <typename CommandLineParserSubclass>
00141 CommandLineOption (
00142 char short_name,
00143 void (CommandLineParserSubclass::*handler_method_without_argument)(),
00144 std::string const &description)
00145 :
00146 m_short_name(short_name),
00147 m_long_name(),
00148 m_requires_an_argument(false),
00149 m_handler_method_with_argument(NULL),
00150 m_handler_method_without_argument(static_cast<HandlerMethodWithoutArgument>(handler_method_without_argument)),
00151 m_description(description)
00152 { }
00153 template <typename CommandLineParserSubclass>
00154 CommandLineOption (
00155 std::string const &long_name,
00156 void (CommandLineParserSubclass::*handler_method_without_argument)(),
00157 std::string const &description)
00158 :
00159 m_short_name('\0'),
00160 m_long_name(long_name),
00161 m_requires_an_argument(false),
00162 m_handler_method_with_argument(NULL),
00163 m_handler_method_without_argument(static_cast<HandlerMethodWithoutArgument>(handler_method_without_argument)),
00164 m_description(description)
00165 { }
00166 template <typename CommandLineParserSubclass>
00167 CommandLineOption (
00168 char short_name,
00169 std::string const &long_name,
00170 void (CommandLineParserSubclass::*handler_method_without_argument)(),
00171 std::string const &description)
00172 :
00173 m_short_name(short_name),
00174 m_long_name(long_name),
00175 m_requires_an_argument(false),
00176 m_handler_method_with_argument(NULL),
00177 m_handler_method_without_argument(static_cast<HandlerMethodWithoutArgument>(handler_method_without_argument)),
00178 m_description(description)
00179 { }
00180
00181 private:
00182
00183 typedef void (CommandLineParser::*HandlerMethodWithArgument)(std::string const &);
00184 typedef void (CommandLineParser::*HandlerMethodWithoutArgument)();
00185
00186 char const m_short_name;
00187 std::string const m_long_name;
00188 bool const m_requires_an_argument;
00189 HandlerMethodWithArgument const m_handler_method_with_argument;
00190 HandlerMethodWithoutArgument const m_handler_method_without_argument;
00191 std::string const m_description;
00192
00193
00194 friend class CommandLineParser;
00195 };
00196
00197 }
00198
00199 #endif // !defined(_XRB_COMMANDLINEPARSER_HPP_)