00001 #pragma ident "$Id: Application.cpp 2974 2011-11-11 09:14:39Z yanweignss $"
00002
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "Application.hpp"
00031 #include "SysInfo.hpp"
00032
00033 namespace gpstk
00034 {
00035 Application* Application::_pInstance = 0;
00036
00037 Application::Application(const std::string& author,
00038 const std::string& version,
00039 const std::string& desc,
00040 const std::string& useage)
00041 : helpRequested(false),unixStyle(true),
00042 _stopOptionsProcessing(false),
00043 _initialized(false)
00044 {
00045 appInfo(author,version,desc,useage);
00046
00047 _pInstance = this;
00048 }
00049
00050 Application::Application(int argc, char* argv[])
00051 : helpRequested(false),unixStyle(true),
00052 _stopOptionsProcessing(false),
00053 _initialized(false)
00054 {
00055 _pInstance = this;
00056
00057 init(argc,argv);
00058 }
00059
00060
00061 void Application::init(int argc, char* argv[])
00062 {
00063 _command = argv[0];
00064 _args.reserve(argc);
00065 for(int i = 0; i < argc; i++)
00066 {
00067 _args.push_back( std::string(argv[i]) );
00068 }
00069 appName = commandName();
00070 processOptions();
00071 }
00072
00073 int Application::run()
00074 {
00075 int rc = EXIT_SOFTWARE;
00076 initialize(*this);
00077 try
00078 {
00079 rc = main(_args);
00080 }
00081 catch (Exception& e)
00082 {
00083 logger().error(e.what());
00084 }
00085 catch (std::exception& e)
00086 {
00087 logger().error(e.what());
00088 }
00089 catch (...)
00090 {
00091 logger().fatal("Unknown system exception");
00092 }
00093
00094 uninitialize();
00095
00096 return rc;
00097 }
00098
00099 void Application::processOptions()
00100 {
00101 defineOptions(_options);
00102
00103 OptionProcessor processor(_options);
00104 processor.setUnixStyle(unixStyle);
00105
00106 _args.erase(_args.begin());
00107
00108 std::vector<std::string>::iterator it = _args.begin();
00109 while (it != _args.end() && !_stopOptionsProcessing)
00110 {
00111 std::string name;
00112 std::string value;
00113 if (processor.process(*it, name, value))
00114 {
00115 if (!name.empty())
00116 {
00117 handleOption(name, value);
00118 }
00119 it = _args.erase(it);
00120 }
00121 else it++;
00122 }
00123 if (!_stopOptionsProcessing) processor.checkRequired();
00124 }
00125
00126 void Application::defineOptions(OptionSet& options)
00127 {
00128 setupOptions(options);
00129
00130 options.addOption(
00131 Option("verbose", "v", "Increase verbosity [0-8]")
00132 .required(false)
00133 .repeatable(true)
00134 .argument("level")
00135 .callback(OptionCallback<Application>(this,
00136 &Application::handleDefaultOptions)));
00137
00138 options.addOption(
00139 Option("help", "h", "Display help information")
00140 .required(false)
00141 .repeatable(false)
00142 .callback(OptionCallback<Application>(this,
00143 &Application::handleDefaultOptions)));
00144
00145 }
00146
00147 void Application::handleOption(const std::string& name,
00148 const std::string& value)
00149 {
00150 const Option& option = _options.getOption(name);
00151
00152 if (option.callback()) option.callback()->invoke(name, value);
00153 }
00154
00155 void Application::handleDefaultOptions(const std::string& name,
00156 const std::string& value)
00157 {
00158
00159 if(name=="help")
00160 {
00161 helpRequested = true;
00162
00163 HelpFormatter helpFormatter(options());
00164 helpFormatter.setUnixStyle(unixStyle);
00165 helpFormatter.setAutoIndent();
00166
00167 std::string helpFooter = commandName() + " " + appVersion + " on ";
00168 helpFooter += SysInfo::osName() + " ["+SysInfo::osArchitecture()+"] ";
00169 helpFooter += "Copyright 2010-2015 "+appAuthor+ ".";
00170
00171
00172 helpFormatter.setCommand(commandName());
00173 helpFormatter.setHeader(appDesc);
00174 helpFormatter.setUsage(appUsage);
00175 helpFormatter.setFooter(helpFooter);
00176
00177 helpFormatter.format(std::cout);
00178
00179 stopOptionsProcessing();
00180 }
00181
00182 if(name=="verbose")
00183 {
00184 verboseLevel = StringUtils::asInt(value);
00185 if(verboseLevel<0 || verboseLevel>8)
00186 {
00187 verboseLevel = 6;
00188 logger().warning("wrong verbose level, and set it to default 6 [information]");
00189 }
00190 }
00191 }
00192
00193 void Application::stopOptionsProcessing()
00194 {
00195 _stopOptionsProcessing = true;
00196 }
00197
00198 void Application::initialize(Application& self)
00199 {
00200 if(!helpRequested)
00201 {
00202 try
00203 {
00204 spinUp();
00205 }
00206 catch(Exception& e)
00207 {
00208 logger().error(std::string("[spinUp] ") + e.what());
00209 }
00210 catch(std::exception& e)
00211 {
00212 logger().error(std::string("[spinUp] ") + e.what());
00213 }
00214 catch(...)
00215 {
00216 logger().error(std::string("[spinUp] ") + "unknown system error.");
00217 }
00218 }
00219
00220 _initialized = true;
00221 }
00222
00223 int Application::main(const std::vector<std::string>& args)
00224 {
00225 if(!helpRequested)
00226 {
00227 try
00228 {
00229 runTime.update();
00230 process(args);
00231 }
00232 catch(Exception& e)
00233 {
00234 logger().error(e.what());
00235 return EXIT_SOFTWARE;
00236 }
00237 catch(std::exception& e)
00238 {
00239 logger().error(e.what());
00240 return EXIT_SOFTWARE;
00241 }
00242 catch(...)
00243 {
00244 logger().error("Unknown system error.");
00245 return EXIT_SOFTWARE;
00246 }
00247 }
00248
00249 return EXIT_OK;
00250 }
00251
00252 void Application::uninitialize()
00253 {
00254 if(!helpRequested)
00255 {
00256 try
00257 {
00258 shutDown();
00259 }
00260 catch(Exception& e)
00261 {
00262 logger().error(std::string("[shutDown] ") + e.what());
00263 }
00264 catch(std::exception& e)
00265 {
00266 logger().error(std::string("[shutDown] ") + e.what());
00267 }
00268 catch(...)
00269 {
00270 logger().error(std::string("[shutDown] ") + "unknown system error.");
00271 }
00272 }
00273
00274 _initialized = false;
00275
00276 }
00277
00278
00279 Logger& Application::logger() const
00280 {
00281 return Logger::get("");
00282 }
00283
00284 LogStream Application::logstream()
00285 {
00286 return LogStream(Logger::get(""));
00287 }
00288
00289 std::string Application::commandName() const
00290 {
00291 std::vector<std::string> paths = split(_command,"/\\");
00292 return (*paths.rbegin());
00293 }
00294
00295 const OptionSet& Application::options() const
00296 {
00297 return _options;
00298 }
00299
00300 double Application::toltalMilliseconds()
00301 {
00302 return runTime.elapsed()*1000.0;
00303 }
00304
00305 Application& Application::appInfo(const std::string& author,
00306 const std::string& version,
00307 const std::string& description,
00308 const std::string& useage)
00309 {
00310 appAuthor = author;
00311 appVersion = version;
00312 appDesc = description;
00313 appUsage = useage;
00314
00315 return (*this);
00316 }
00317
00318
00319 }
00320