/*
* opencog/cogserver/modules/BuiltinRequestsModule.cc
*
* Copyright (C) 2008,2010 by OpenCog Foundation
* Written by Gustavo Gama <gama@vettalabs.com>
* Written by Joel Pitt <joel@opencog.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License v3 as
* published by the Free Software Foundation and including the exceptions
* at http://opencog.org/wiki/Licenses
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, write to:
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <iomanip>
#include <unistd.h>
#include <opencog/util/oc_assert.h>
#include <opencog/cogserver/atoms/CogServerNode.h>
#include <opencog/network/ConsoleSocket.h>
#include "BuiltinRequestsModule.h"
using namespace opencog;
//!@{
//! color codes in ANSI
static const char* const COLOR_OFF = "\033[0m";
static const char* const BRIGHT = "\033[1m";
static const char* const RED = "\033[31m";
static const char* const GREEN = "\033[32m";
static const char* const YELLOW = "\033[33m";
static const char* const BLUE = "\033[34m";
static const char* const MAGENTA = "\033[35m";
static const char* const CYAN = "\033[36m";
static const char* const WHITE = "\033[37m";
//!@}
inline void ansi_code(std::string &s,const std::string &code) {
s.append(code);
}
//!@{
static inline void ansi_off(std::string &s) { ansi_code(s,COLOR_OFF); }
static inline void ansi_bright(std::string &s) { ansi_code(s,BRIGHT); }
static inline void ansi_red(std::string &s) { ansi_code(s,RED); }
static inline void ansi_green(std::string &s) { ansi_code(s,GREEN); }
static inline void ansi_yellow(std::string &s) { ansi_code(s,YELLOW); }
static inline void ansi_blue(std::string &s) { ansi_code(s,BLUE); }
static inline void ansi_magenta(std::string &s) { ansi_code(s,MAGENTA); }
static inline void ansi_cyan(std::string &s) { ansi_code(s,CYAN); }
static inline void ansi_white(std::string &s) { ansi_code(s,WHITE); }
//!@}
DECLARE_MODULE(BuiltinRequestsModule)
BuiltinRequestsModule::BuiltinRequestsModule(const Handle& hcsn) : Module(hcsn)
{
CogServer* cs = CogServerNodeCast(hcsn).get();
cs->registerRequest(ShutdownRequest::info().id, &shutdownFactory);
cs->registerRequest(ListModulesRequest::info().id, &listmodulesFactory);
cs->registerRequest(LoadModuleRequest::info().id, &loadmoduleFactory);
cs->registerRequest(UnloadModuleRequest::info().id, &unloadmoduleFactory);
do_help_register();
do_h_register();
do_exit_register();
do_quit_register();
do_q_register();
do_ctrld_register();
do_iaceof_register();
do_dot_register();
do_stats_register();
}
BuiltinRequestsModule::~BuiltinRequestsModule()
{
do_help_unregister();
do_h_unregister();
do_exit_unregister();
do_quit_unregister();
do_q_unregister();
do_ctrld_unregister();
do_iaceof_unregister();
do_dot_unregister();
do_stats_unregister();
CogServer* cs = CogServerNodeCast(_hcsn).get();
cs->unregisterRequest(ShutdownRequest::info().id);
cs->unregisterRequest(ListModulesRequest::info().id);
cs->unregisterRequest(LoadModuleRequest::info().id);
cs->unregisterRequest(UnloadModuleRequest::info().id);
}
void BuiltinRequestsModule::init()
{
}
// ====================================================================
// Various flavors of closing the connection
std::string BuiltinRequestsModule::do_exit(Request* req, std::list<std::string> args)
{
ConsoleSocket* con = req->get_console();
OC_ASSERT(con, "Bad request state");
con->Exit();
// After the exit, the pointer to the console will be invalid,
// so zero it out now, to avoid a bad dereference. (Note that
// this call may trigger the ConsoleSocket dtor to run).
req->set_console(nullptr);
return "";
}
std::string BuiltinRequestsModule::do_quit(Request *req, std::list<std::string> args)
{
return do_exit(req, args);
}
std::string BuiltinRequestsModule::do_q(Request *req, std::list<std::string> args)
{
return do_exit(req, args);
}
std::string BuiltinRequestsModule::do_ctrld(Request *req, std::list<std::string> args)
{
return do_exit(req, args);
}
std::string BuiltinRequestsModule::do_iaceof(Request *req, std::list<std::string> args)
{
return do_exit(req, args);
}
std::string BuiltinRequestsModule::do_dot(Request *req, std::list<std::string> args)
{
return do_exit(req, args);
}
// ====================================================================
// Various flavors of help
std::string BuiltinRequestsModule::do_help(Request *req, std::list<std::string> args)
{
std::ostringstream oss;
CogServer* cs = CogServerNodeCast(_hcsn).get();
if (args.empty()) {
std::list<const char*> commands = cs->requestIds();
size_t maxl = 0;
std::list<const char*>::const_iterator it;
for (it = commands.begin(); it != commands.end(); ++it) {
size_t len = strlen(*it);
if (len > maxl) maxl = len;
}
oss << "Available commands:" << std::endl;
for (it = commands.begin(); it != commands.end(); ++it) {
// Skip hidden commands
if (cs->requestInfo(*it).hidden) continue;
std::string cmdname(*it);
std::string ansi_cmdname;
ansi_green(ansi_cmdname); ansi_bright(ansi_cmdname);
ansi_cmdname.append(cmdname);
ansi_off(ansi_cmdname);
ansi_green(ansi_cmdname);
ansi_cmdname.append(":");
ansi_off(ansi_cmdname);
size_t cmd_length = strlen(cmdname.c_str());
size_t ansi_code_length = strlen(ansi_cmdname.c_str()) - cmd_length;
oss << " " << std::setw(maxl+ansi_code_length+2) << std::left << ansi_cmdname
<< cs->requestInfo(*it).description << std::endl;
}
} else if (args.size() == 1) {
const RequestClassInfo& cci = cs->requestInfo(args.front());
if (cci.help != "")
oss << cci.help << std::endl;
} else {
oss << do_helpRequest::info().help << std::endl;
}
return oss.str();
}
std::string BuiltinRequestsModule::do_h(Request *req, std::list<std::string> args)
{
return do_help(req, args);
}
// ====================================================================
// Print general info about server.
std::string BuiltinRequestsModule::do_stats(Request *req, std::list<std::string> args)
{
return CogServerNodeCast(_hcsn)->display_stats();
}
// ====================================================================