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