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 //----------------------------------------------------------------------------