Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

SgGtpCommands.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file SgGtpCommands.cpp
00003     See SgGtpCommands.h
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 } // namespace
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 /** Run another GTP command and compare its response against a float value.
00076     Arguments: float command [arg...] <br>
00077     Returns: -1 if response is smaller than float; 1 otherwise.
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 /** Run another GTP command and compare its response against an integer value.
00092     Arguments: int command [arg...] <br>
00093     Returns: -1 if response is smaller than int; 0 if it is equal; 1 if it is
00094     greater
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 /** Return process time.
00115     An optional string argument can be used as an ID for a timer.
00116     Default ID is "total".
00117     Other IDs are only allowed if cputime_reset was called with this ID
00118     before.
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 /** Reset process time.
00137     An optional string argument can be used as an ID for a timer.
00138     Default ID is "total".
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 /** Run a debugger and attach it to the current program.
00148     Arguments: debugger-type <br>
00149     Currently implemented debugger types:
00150     - gdb_kde GDB in KDE terminal
00151     - gdb_gnome GDB in GNOME terminal
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 /** Echo command argument line as response.
00175     This command is compatible with GNU Go's 'echo' command.
00176 */
00177 void SgGtpCommands::CmdEcho(GtpCommand& cmd)
00178 {
00179     cmd << cmd.ArgLine();
00180 }
00181 
00182 /** Echo command argument line to std::cerr.
00183     This command is compatible with GNU Go's 'echo_err' command.
00184 */
00185 void SgGtpCommands::CmdEchoErr(GtpCommand& cmd)
00186 {
00187     string line = cmd.ArgLine();
00188     cerr << line << endl;
00189     cmd << line;
00190 }
00191 
00192 /** Execute GTP commands from a file.
00193     Argument: filename <br>
00194     Aborts on the first command that fails. Responses to the commands in the
00195     file are written to SgDebug()
00196     @see GtpEngine::ExecuteFile
00197 */
00198 void SgGtpCommands::CmdExec(GtpCommand& cmd)
00199 {
00200     cmd.CheckNuArg(1);
00201     m_engine.ExecuteFile(cmd.Arg(0), SgDebug());
00202 }
00203 
00204 /** Return the current random seed.
00205     See SgRandom::SetSeed(int) for the special meaning of zero and negative
00206     values.
00207 */
00208 void SgGtpCommands::CmdGetRandomSeed(GtpCommand& cmd)
00209 {
00210     cmd.CheckArgNone();
00211     cmd << SgRandom::Seed();
00212 }
00213 
00214 /** Set global parameters used in module SmartGame.
00215     Parameters:
00216     @arg @c time_mode cpu|real See SgTime
00217 */
00218 void SgGtpCommands::CmdParam(GtpCommand& cmd)
00219 {
00220     cmd.CheckNuArgLessEqual(2);
00221     if (cmd.NuArg() == 0)
00222     {
00223         // Boolean parameters first for better layout of GoGui parameter
00224         // dialog, alphabetically otherwise
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 /** Return the process ID. */
00241 void SgGtpCommands::CmdPid(GtpCommand& cmd)
00242 {
00243     cmd.CheckArgNone();
00244     cmd << getpid();
00245 }
00246 
00247 /** Set and store random seed.
00248     Arguments: seed <br>
00249     See SgRandom::SetSeed(int) for the special meaning of zero and negative
00250     values.
00251 */
00252 void SgGtpCommands::CmdSetRandomSeed(GtpCommand& cmd)
00253 {
00254     cmd.CheckNuArg(1);
00255     SgRandom::SetSeed(cmd.IntArg(0));
00256 }
00257 
00258 /** Switch debug logging on/off. */
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 


17 Jun 2010 Doxygen 1.4.7