Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

HexProgram.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file HexProgram.cpp
00003  */
00004 //----------------------------------------------------------------------------
00005 
00006 #include "SgSystem.h"
00007 
00008 #include "BoardUtils.hpp"
00009 #include "HexProp.hpp"
00010 #include "HexProgram.hpp"
00011 #include "Resistance.hpp"
00012 #include "RingGodel.hpp"
00013 #include "Time.hpp"
00014 
00015 #include <boost/program_options/cmdline.hpp>
00016 #include <boost/program_options/variables_map.hpp>
00017 #include <boost/program_options/parsers.hpp>
00018 
00019 namespace po = boost::program_options;
00020 
00021 using namespace benzene;
00022 
00023 //----------------------------------------------------------------------------
00024 
00025 namespace 
00026 {
00027     std::ofstream g_logfile;
00028 }
00029 
00030 //----------------------------------------------------------------------------
00031 
00032 HexProgram::HexProgram()
00033     : m_initialized(false),
00034       m_options_desc("Options")
00035 {
00036 }
00037 
00038 HexProgram::~HexProgram()
00039 {
00040 }
00041 
00042 HexProgram& HexProgram::Get()
00043 {
00044     static HexProgram program;
00045     return program;
00046 }
00047 
00048 void HexProgram::SetInfo(std::string name, std::string version, 
00049                          std::string date)
00050 {
00051     m_name = name;
00052     m_version = version;
00053     m_date = date;
00054 }
00055 
00056 void HexProgram::PrintStartupMessage()
00057 {
00058     std::cerr <<
00059         m_name << " " << m_version << " " << m_date << "\n"
00060         "Copyright (C) 2010 by the authors of the Benzene project.\n"
00061         "This program comes with ABSOLUTELY NO WARRANTY. This is\n"
00062         "free software and you are welcome to redistribute it under\n"
00063         "certain conditions. Type `benzene-license' for details.\n\n";
00064 }
00065 
00066 //----------------------------------------------------------------------------
00067 
00068 void HexProgram::RegisterCmdLineArguments()
00069 {
00070     m_options_desc.add_options()
00071         ("help", "Displays this usage information.")
00072         ("usage", "Displays this usage information.")
00073         ("version", "Displays version information.")
00074         ("quiet", "Suppresses log output to stderr.")
00075         ("verbose", "Displays more logging output to stderr.")
00076         ("use-logfile", 
00077          po::value<bool>(&m_use_logfile)->default_value(true),
00078          "Whether to use a .log file or not.")
00079         ("logfile-name", 
00080          po::value<std::string>(&m_logfile_name)->default_value("default.log"),
00081          "Specify name of log file.")
00082         ("logfile-level",
00083          po::value<std::string>(&m_logfile_level)->default_value("config"),
00084          "Message level for log file.")
00085         ("boardsize", 
00086          po::value<int>(&m_boardsize)->default_value(11),
00087          "Sets the size of the board.")
00088         ("config", 
00089          po::value<std::string>(&m_config_file)->default_value(""),
00090          "Sets the config file to parse.")
00091         ("seed", 
00092          po::value<int>(&m_random_seed)->default_value(-1),
00093          "Sets the seed for the random number generator. "
00094          "(-1 for current time)");
00095 }
00096 
00097 void HexProgram::InitLog()
00098 {
00099     // remove default streams and add our own
00100     Logger::Global().ClearStreams();
00101     Logger::Global().AddStream(std::cerr, m_stderr_level);
00102 
00103     if (m_use_logfile)
00104     {
00105         g_logfile.open(m_logfile_name.c_str());
00106         if (!g_logfile)
00107             LogWarning() 
00108                      << "Could not open log file ('" << m_logfile_name << "') "
00109                      << "for writing! No log file will be used." << '\n';
00110     }
00111     if (g_logfile) 
00112     {
00113         LogLevel level = LogLevelUtil::fromString(m_logfile_level);
00114         Logger::Global().AddStream(g_logfile, level);
00115     } 
00116 }
00117 
00118 void HexProgram::InitRandom()
00119 {
00120     LogConfig()<< "HexProgram::InitRandom()" << '\n';
00121     if (m_random_seed == -1) {
00122         m_random_seed = static_cast<int>(time(NULL));
00123     }
00124     LogConfig() << "Seed = " << m_random_seed << '\n';
00125     SgRandom::SetSeed(m_random_seed);
00126 }
00127 
00128 void HexProgram::InitializeHexSystem()
00129 {
00130     InitLog();
00131     LogConfig() << m_name << " v" << m_version << " " << m_date << "." << '\n';
00132     LogConfig() << "============ InitializeHexSystem ============" << '\n';
00133     SgProp::Init();
00134     HexProp::Init();
00135     InitRandom();
00136     BoardUtils::InitializeDecompositions();
00137     ResistanceUtil::Initialize();
00138 }
00139 
00140 void HexProgram::Initialize(int argc, char **argv)
00141 {
00142     if (m_initialized)
00143         return;
00144 
00145     // store the name of the executable
00146     m_executable_name = argv[0];
00147     
00148     // determine the executable directory
00149     {
00150         std::string path = m_executable_name;    
00151         std::string::size_type loc = path.rfind('/', path.length()-1);
00152         if (loc == std::string::npos) {
00153             path = "";
00154         } else {
00155             path = path.substr(0, loc);
00156             path.append("/");
00157         }
00158         m_executable_path = path;
00159     }
00160 
00161     RegisterCmdLineArguments();
00162     ProcessCmdLineArguments(argc, argv);
00163     InitializeHexSystem();
00164 }
00165 
00166 //----------------------------------------------------------------------------
00167 
00168 void HexProgram::ShutdownLog()
00169 {
00170     Logger::Global().Flush();
00171     if (g_logfile)
00172     {
00173         g_logfile << "Flushing and closing this stream...\n";
00174         g_logfile.flush();
00175     }
00176     g_logfile.close();
00177 }
00178 
00179 void HexProgram::Shutdown()
00180 {
00181     LogConfig() << "============ HexShutdown =============" << '\n';
00182     ShutdownLog();
00183 }
00184 
00185 //----------------------------------------------------------------------------
00186 
00187 void HexProgram::ProcessCmdLineArguments(int argc, char** argv)
00188 {
00189     po::variables_map vm;
00190     try
00191     {
00192         po::store(po::parse_command_line(argc, argv, m_options_desc), vm);
00193         po::notify(vm);
00194     }
00195     catch(...)
00196     {
00197         Usage();
00198         Shutdown();
00199         exit(1);
00200     }
00201     
00202     if (vm.count("usage") || vm.count("help"))
00203     {
00204         Usage();
00205         Shutdown();
00206         exit(1);
00207     }
00208 
00209     if (vm.count("version"))
00210     {
00211         std::cout << m_name;
00212         std::cout << " v" << m_version;
00213         std::cout << " " << m_date << "." << std::endl;
00214         Shutdown();
00215         exit(0);
00216     }
00217 
00218     m_stderr_level = LOG_LEVEL_INFO;
00219     if (vm.count("quiet"))
00220         m_stderr_level = LOG_LEVEL_OFF;
00221     if (vm.count("verbose"))
00222         m_stderr_level = LOG_LEVEL_ALL;
00223     
00224 }
00225 
00226 void HexProgram::Usage() const
00227 {
00228     std::cout << std::endl
00229               << "Usage: " 
00230               << std::endl 
00231               << "       " << m_executable_name << " [Options]" 
00232               << std::endl << std::endl;
00233     
00234     std::cout << "[OPTIONS] is any number of the following:"
00235               << std::endl << std::endl;
00236     
00237     std::cout << m_options_desc << std::endl;
00238 
00239     std::cout << std::endl;
00240 }
00241 
00242 //----------------------------------------------------------------------------
00243 
00244 void HexAssertShutdown(const char* assertion, const char* file, int line,
00245                        const char* function)
00246 {
00247     std::ostringstream os;
00248     os << file << ":" << line << ": " << function << ": "
00249        << "Assertion `" << assertion << "' failed.";
00250     LogSevere() << os.str() << '\n';
00251     
00252     HexProgram::Get().Shutdown();
00253 
00254     abort();
00255 }
00256 
00257 //----------------------------------------------------------------------------


6 Jan 2011 Doxygen 1.6.3