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


Sun Mar 13 2011 Doxygen 1.7.1