Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "SgSystem.h"
00007 #include "SgGtpCommands.h"
00008
00009 #include <iomanip>
00010 #include <iostream>
00011 #if ! WIN32
00012 #include <unistd.h>
00013 #endif
00014 #include "SgDebug.h"
00015 #include "SgRandom.h"
00016 #include "SgTime.h"
00017
00018 using namespace std;
00019
00020
00021
00022 namespace {
00023
00024 string ParseCpuTimeId(const GtpCommand& cmd)
00025 {
00026 cmd.CheckNuArgLessEqual(1);
00027 if (cmd.NuArg() > 0)
00028 return cmd.Arg(0);
00029 return "total";
00030 }
00031
00032 SgTimeMode TimeModeArg(const GtpCommand& cmd, size_t number)
00033 {
00034 string arg = cmd.ArgToLower(number);
00035 if (arg == "cpu")
00036 return SG_TIME_CPU;
00037 if (arg == "real")
00038 return SG_TIME_REAL;
00039 throw GtpFailure() << "unknown time mode argument \"" << arg << '"';
00040 }
00041
00042 string TimeModeToString(SgTimeMode mode)
00043 {
00044 switch (mode)
00045 {
00046 case SG_TIME_CPU:
00047 return "cpu";
00048 case SG_TIME_REAL:
00049 return "real";
00050 default:
00051 SG_ASSERT(false);
00052 return "?";
00053 }
00054 }
00055
00056 }
00057
00058
00059
00060 SgGtpCommands::SgGtpCommands(GtpEngine& engine, const char* programPath)
00061 : m_programPath(programPath),
00062 m_engine(engine)
00063 {
00064 }
00065
00066 SgGtpCommands::~SgGtpCommands()
00067 {
00068 }
00069
00070 void SgGtpCommands::AddGoGuiAnalyzeCommands(GtpCommand& cmd)
00071 {
00072 cmd <<
00073 "param/SmartGame Param/sg_param\n";
00074 }
00075
00076
00077
00078
00079 void SgGtpCommands::CmdCompareFloat(GtpCommand& cmd)
00080 {
00081 double value = cmd.Arg<double>(0);
00082 string response = m_engine.ExecuteCommand(cmd.RemainingLine(0));
00083 istringstream in(response);
00084 double responseValue;
00085 in >> responseValue;
00086 if (! in)
00087 throw GtpFailure() << "response '" << response << "' is not a float";
00088 cmd << (responseValue < value ? "-1" : "1");
00089 }
00090
00091
00092
00093
00094
00095 void SgGtpCommands::CmdCompareInt(GtpCommand& cmd)
00096 {
00097 int value = cmd.Arg<int>(0);
00098 string response = m_engine.ExecuteCommand(cmd.RemainingLine(0));
00099 istringstream in(response);
00100 int responseValue;
00101 in >> responseValue;
00102 if (! in)
00103 throw GtpFailure() << "response '" << response
00104 << "' is not an integer";
00105 if (responseValue == value)
00106 cmd << "0";
00107 else if (responseValue < value)
00108 cmd << "-1";
00109 else
00110 cmd << "1";
00111 }
00112
00113
00114
00115
00116
00117
00118 void SgGtpCommands::CmdCpuTime(GtpCommand& cmd)
00119 {
00120
00121 string id = ParseCpuTimeId(cmd);
00122 double timeNow = SgTime::Get(SG_TIME_CPU);
00123 double timeDiff = timeNow;
00124 if (m_cpuTimes.find(id) == m_cpuTimes.end())
00125 {
00126 if (id != "total")
00127 throw GtpFailure() << "unknown cputime id " << id;
00128 }
00129 else
00130 timeDiff -= m_cpuTimes[id];
00131 cmd << fixed << setprecision(3) << timeDiff;
00132 }
00133
00134
00135
00136
00137 void SgGtpCommands::CmdCpuTimeReset(GtpCommand& cmd)
00138 {
00139 string id = ParseCpuTimeId(cmd);
00140 double timeNow = SgTime::Get(SG_TIME_CPU);
00141 m_cpuTimes[id] = timeNow;
00142 }
00143
00144
00145
00146
00147
00148
00149 void SgGtpCommands::CmdDebugger(GtpCommand& cmd)
00150 {
00151 #if WIN32
00152 throw GtpFailure("command not implemented on Windows");
00153 #else
00154 string type = cmd.Arg();
00155 const char* path = m_programPath;
00156 if (path == 0)
00157 throw GtpFailure("location of executable unknown");
00158 pid_t pid = getpid();
00159 ostringstream s;
00160 if (type == "gdb_kde")
00161 s << "konsole -e gdb " << path << ' ' << pid << " &";
00162 else if (type == "gdb_gnome")
00163 s << "gnome-terminal -e 'gdb " << path << ' ' << pid << "' &";
00164 else
00165 throw GtpFailure() << "unknown debugger: " << type;
00166 SgDebug() << "Executing: " << s.str() << '\n';
00167 int retval = system(s.str().c_str());
00168 if (retval != 0)
00169 throw GtpFailure() << "command returned " << retval;
00170 #endif
00171 }
00172
00173
00174
00175 void SgGtpCommands::CmdEcho(GtpCommand& cmd)
00176 {
00177 cmd << cmd.ArgLine();
00178 }
00179
00180
00181
00182 void SgGtpCommands::CmdEchoErr(GtpCommand& cmd)
00183 {
00184 string line = cmd.ArgLine();
00185 cerr << line << endl;
00186 cmd << line;
00187 }
00188
00189
00190
00191
00192
00193
00194 void SgGtpCommands::CmdExec(GtpCommand& cmd)
00195 {
00196 m_engine.ExecuteFile(cmd.Arg(), SgDebug());
00197 }
00198
00199
00200
00201
00202 void SgGtpCommands::CmdGetRandomSeed(GtpCommand& cmd)
00203 {
00204 cmd.CheckArgNone();
00205 cmd << SgRandom::Seed();
00206 }
00207
00208
00209
00210
00211 void SgGtpCommands::CmdParam(GtpCommand& cmd)
00212 {
00213 cmd.CheckNuArgLessEqual(2);
00214 if (cmd.NuArg() == 0)
00215 {
00216
00217
00218 cmd << "[list/cpu/real] time_mode "
00219 << TimeModeToString(SgTime::DefaultMode()) << '\n';
00220 }
00221 else if (cmd.NuArg() >= 1 && cmd.NuArg() <= 2)
00222 {
00223 string name = cmd.Arg(0);
00224 if (name == "time_mode")
00225 SgTime::SetDefaultMode(TimeModeArg(cmd, 1));
00226 else
00227 throw GtpFailure() << "unknown parameter: " << name;
00228 }
00229 else
00230 throw GtpFailure() << "need 0 or 2 arguments";
00231 }
00232
00233
00234 void SgGtpCommands::CmdPid(GtpCommand& cmd)
00235 {
00236 #if WIN32
00237 throw GtpFailure("command not implemented on Windows");
00238 #else
00239 cmd.CheckArgNone();
00240 cmd << getpid();
00241 #endif
00242 }
00243
00244
00245
00246
00247
00248 void SgGtpCommands::CmdSetRandomSeed(GtpCommand& cmd)
00249 {
00250 SgRandom::SetSeed(cmd.Arg<int>());
00251 }
00252
00253
00254 void SgGtpCommands::CmdQuiet(GtpCommand& cmd)
00255 {
00256 if (cmd.Arg<bool>())
00257 SgDebugToNull();
00258 else
00259 SgSwapDebugStr(&cerr);
00260 }
00261
00262 void SgGtpCommands::Register(GtpEngine& engine)
00263 {
00264 engine.Register("cputime", &SgGtpCommands::CmdCpuTime, this);
00265 engine.Register("cputime_reset", &SgGtpCommands::CmdCpuTimeReset, this);
00266 engine.Register("echo", &SgGtpCommands::CmdEcho, this);
00267 engine.Register("echo_err", &SgGtpCommands::CmdEchoErr, this);
00268 engine.Register("get_random_seed", &SgGtpCommands::CmdGetRandomSeed, this);
00269 engine.Register("pid", &SgGtpCommands::CmdPid, this);
00270 engine.Register("set_random_seed", &SgGtpCommands::CmdSetRandomSeed, this);
00271 engine.Register("sg_debugger", &SgGtpCommands::CmdDebugger, this);
00272 engine.Register("sg_compare_float", &SgGtpCommands::CmdCompareFloat, this);
00273 engine.Register("sg_compare_int", &SgGtpCommands::CmdCompareInt, this);
00274 engine.Register("sg_exec", &SgGtpCommands::CmdExec, this);
00275 engine.Register("sg_param", &SgGtpCommands::CmdParam, this);
00276 engine.Register("quiet", &SgGtpCommands::CmdQuiet, this);
00277 }
00278
00279
00280