Application.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: Application.cpp 2974 2011-11-11 09:14:39Z yanweignss $"
00002 
00008 //============================================================================
00009 //
00010 //  This file is part of GPSTk, the GPS Toolkit.
00011 //
00012 //  The GPSTk is free software; you can redistribute it and/or modify
00013 //  it under the terms of the GNU Lesser General Public License as published
00014 //  by the Free Software Foundation; either version 2.1 of the License, or
00015 //  any later version.
00016 //
00017 //  The GPSTk is distributed in the hope that it will be useful,
00018 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //  GNU Lesser General Public License for more details.
00021 //
00022 //  You should have received a copy of the GNU Lesser General Public
00023 //  License along with GPSTk; if not, write to the Free Software Foundation,
00024 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 //
00026 //  Wei Yan - Chinese Academy of Sciences . 2011
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()) // "--" option to end options processing
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       // Help
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    }  // End of method 'Application::uninitialize()'
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 }   // End of namespace gpstk
00320 

Generated on Tue May 22 03:30:56 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1