mirror of
https://github.com/SWG-Source/src.git
synced 2026-07-31 00:15:55 -04:00
Added sharedCommandParser library
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
|
||||
add_subdirectory(sharedCollision)
|
||||
add_subdirectory(sharedCommandParser)
|
||||
add_subdirectory(sharedCompression)
|
||||
add_subdirectory(sharedDebug)
|
||||
add_subdirectory(sharedFile)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(sharedCommandParser)
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/public)
|
||||
|
||||
add_subdirectory(src)
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/CommandParser.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/CommandParserHistory.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/CommandPermissionManager.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/FirstSharedCommandParser.h"
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
set(SHARED_SOURCES
|
||||
shared/CommandParser.cpp
|
||||
shared/CommandParser.h
|
||||
shared/CommandParserHistory.cpp
|
||||
shared/CommandParserHistory.h
|
||||
shared/CommandPermissionManager.cpp
|
||||
shared/CommandPermissionManager.h
|
||||
shared/FirstSharedCommandParser.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(PLATFORM_SOURCES
|
||||
win32/FirstSharedCommandParser.cpp
|
||||
)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32)
|
||||
else()
|
||||
set(PLATFORM_SOURCES "")
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shared
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedSynchronization/include/public
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include
|
||||
)
|
||||
|
||||
add_library(sharedCommandParser STATIC
|
||||
${SHARED_SOURCES}
|
||||
${PLATFORM_SOURCES}
|
||||
)
|
||||
@@ -0,0 +1,750 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CommandParser.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedCommandParser/FirstSharedCommandParser.h"
|
||||
#include "sharedCommandParser/CommandParser.h"
|
||||
#include "sharedCommandParser/CommandPermissionManager.h"
|
||||
|
||||
#include "sharedFoundation/NetworkId.h"
|
||||
#include "UnicodeUtils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
//- TODO: load these messages from the StringTable to localize the commandparser - jww
|
||||
|
||||
static const CommandParser::ErrorInfoData errors[static_cast<size_t>(CommandParser::ERR_NUM_ERRS)+1] =
|
||||
{
|
||||
{CommandParser::ERR_NONE, "None - error!"},
|
||||
{CommandParser::ERR_SUCCESS, "Command completed succesfully."},
|
||||
{CommandParser::ERR_FAIL, "Command failed!"},
|
||||
{CommandParser::ERR_NO_ERROR_MSG, "No error message available!"},
|
||||
{CommandParser::ERR_CMD_NOT_FOUND, "Command not found."},
|
||||
{CommandParser::ERR_SUBCMD_NOT_FOUND, "Subcommand not found."},
|
||||
{CommandParser::ERR_NO_HANDLER, "No handler for this command."},
|
||||
{CommandParser::ERR_NO_SCENE, "No scene available."},
|
||||
{CommandParser::ERR_SCENE_INVALID_OPERATION, "Scene does not support this operation."},
|
||||
{CommandParser::ERR_INVALID_ARGUMENTS, "Invalid arguments."},
|
||||
{CommandParser::ERR_NOT_ENOUGH_ARGUMENTS, "Not enough arguments."},
|
||||
{CommandParser::ERR_NO_AVATAR, "No avatar found!"},
|
||||
{CommandParser::ERR_SENDING_COMMAND_TO_SERVER, "Sending command to server."},
|
||||
{CommandParser::ERR_NO_CONTROLLER, "No controller found!"},
|
||||
{CommandParser::ERR_NO_NODES, "No CommandParser nodes attached."},
|
||||
{CommandParser::ERR_NO_SUBCOMMAND_SPECIFIED, "No subcommand specified. Subcommands:\n"},
|
||||
{CommandParser::ERR_NO_PARSER_IMPLEMENTED, "No parser implemented!"},
|
||||
{CommandParser::ERR_INVALID_OBJECT, "Invalid object."},
|
||||
{CommandParser::ERR_INVALID_SCRIPT, "Invalid script name or other error."},
|
||||
{CommandParser::ERR_INVALID_TRIGGER, "Invalid trigger id."},
|
||||
{CommandParser::ERR_NOT_SKUFREE_TEMPLATE, "Can't create a non skufree asset in a free trial area."},
|
||||
{CommandParser::ERR_SCRIPT_CONTINUE, "Trigger returns SCRIPT_CONTINUE"},
|
||||
{CommandParser::ERR_SCRIPT_OVERRIDE, "Trigger returns SCRIPT_OVERRIDE"},
|
||||
{CommandParser::ERR_UNSUPPORTED_TRIGGER, "Cannot invoke trigger from the command line."},
|
||||
{CommandParser::ERR_INVALID_PARAMETER_COUNT, "Wrong number of parameters for trigger, needed "},
|
||||
{CommandParser::ERR_INVALID_OBJVAR, "Cannot find objvar."},
|
||||
{CommandParser::ERR_LIST_OBJVAR_NOT_SUPPORTED, "Objvar type = list, function not supported."},
|
||||
{CommandParser::ERR_INVALID_INT_OBJVAR, "Invalid data for int objvar."},
|
||||
{CommandParser::ERR_INVALID_REAL_OBJVAR, "Invalid data for real objvar."},
|
||||
{CommandParser::ERR_PERMISSION_DENIED, "Permission denied."},
|
||||
{CommandParser::ERR_NO_TERRAIN, "Scene does not have a terrain."},
|
||||
{CommandParser::ERR_TERRAIN_GENERATION, "Could not generate terrain at these coords."},
|
||||
{CommandParser::ERR_INVALID_USER, "The user issuing the command was not found."},
|
||||
{CommandParser::ERR_NO_TARGET_OBJECT, "The target given was not found."},
|
||||
{CommandParser::ERR_BAD_ATTACKER, "The attacker is not a tangible object."},
|
||||
{CommandParser::ERR_BAD_DEFENDER, "The target is not a tangible object."},
|
||||
{CommandParser::ERR_QUEUE_COMMAND_FAIL, "Failed to queue command."},
|
||||
{CommandParser::ERR_CANNOT_XFER_AUTH, "Request to transfer authority denied."},
|
||||
{CommandParser::ERR_INVALID_TEMPLATE, "Invalid Object template specified."},
|
||||
{CommandParser::ERR_INVALID_CONTAINER_TRANSFER, "Invalid Container Transfer."},
|
||||
{CommandParser::ERR_FILE_NOT_FOUND, "File not found."},
|
||||
{CommandParser::ERR_INVALID_INGREDIENT, "Invalid ingredient."},
|
||||
{CommandParser::ERR_INVALID_STATION, "Object not a crafting station."},
|
||||
{CommandParser::ERR_STATION_IN_USE, "Crafting station in use."},
|
||||
{CommandParser::ERR_FILLSLOT_FAIL, "Error filling the schematic slot."},
|
||||
{CommandParser::ERR_CUSTOMIZE_FAIL, "Error setting customization property."},
|
||||
{CommandParser::ERR_TEMPLATE_NOT_LOADED, "Template Not Loaded"},
|
||||
{CommandParser::ERR_ACTIVE_MANF_STATION, "Manufacturing station active, please turn off."},
|
||||
{CommandParser::ERR_SCRIPTING_ENABLED, "Scripting is enabled."},
|
||||
{CommandParser::ERR_SCRIPTING_DISABLED, "Scripting is disabled."},
|
||||
{CommandParser::ERR_NUM_ERRS, ""}
|
||||
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
const Unicode::String s_alias_cmd = Unicode::narrowToWide ("alias");
|
||||
const Unicode::String s_alias_cmd_slash = Unicode::narrowToWide ("/") + s_alias_cmd;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
CommandParser::String_t * CommandParser::ms_ERR_NO_ERROR_MSG_MSG;
|
||||
CommandParser::ErrorMsgMap_t * CommandParser::ms_errorMsgMap;
|
||||
size_t CommandParser::ms_instanceCount;
|
||||
const CommandPermissionManager * CommandParser::ms_permissionManager;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
CommandParser::CommandParser (const String_t & cmd,
|
||||
size_t minArgs,
|
||||
const String_t & args,
|
||||
const String_t & help,
|
||||
CommandParser * delegate) :
|
||||
m_cmd (cmd),
|
||||
m_minArgs (minArgs),
|
||||
m_args (args),
|
||||
m_help (help),
|
||||
m_default (false),
|
||||
m_parent (0),
|
||||
m_delegate (delegate),
|
||||
m_subCommands (NON_NULL (new CommandParserSet_t))
|
||||
{
|
||||
++ms_instanceCount;
|
||||
initStatics ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
CommandParser::CommandParser (const char * const cmd,
|
||||
size_t minArgs,
|
||||
const char * const args,
|
||||
const char * const help,
|
||||
CommandParser * delegate) :
|
||||
m_cmd (),
|
||||
m_minArgs (minArgs),
|
||||
m_args (),
|
||||
m_help (),
|
||||
m_default (false),
|
||||
m_parent (0),
|
||||
m_delegate (delegate),
|
||||
m_subCommands (NON_NULL (new CommandParserSet_t))
|
||||
{
|
||||
++ms_instanceCount;
|
||||
initStatics ();
|
||||
|
||||
std::string cmd_narrow (cmd);
|
||||
m_cmd.append (cmd_narrow.begin (), cmd_narrow.end ());
|
||||
|
||||
std::string args_narrow (args);
|
||||
m_args.append (args_narrow.begin (), args_narrow.end ());
|
||||
|
||||
std::string help_narrow (help);
|
||||
m_help.append (help_narrow.begin (), help_narrow.end ());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
CommandParser::CommandParser (const CommandParser::CmdInfo & info, CommandParser * delegate) :
|
||||
m_cmd (Unicode::narrowToWide (info.m_cmd)),
|
||||
m_minArgs (info.m_minArgs),
|
||||
m_args (Unicode::narrowToWide (info.m_args)),
|
||||
m_help (Unicode::narrowToWide (info.m_help)),
|
||||
m_default (false),
|
||||
m_parent (0),
|
||||
m_delegate (delegate),
|
||||
m_subCommands (NON_NULL (new CommandParserSet_t))
|
||||
{
|
||||
++ms_instanceCount;
|
||||
initStatics ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
void CommandParser::initStatics (void)
|
||||
{
|
||||
if (ms_errorMsgMap == 0)
|
||||
{
|
||||
ms_errorMsgMap = new ErrorMsgMap_t;
|
||||
|
||||
for (int i = 0; ; ++i)
|
||||
{
|
||||
const CommandParser::ErrorInfoData & infoData = errors [i];
|
||||
|
||||
if (infoData.m_type == ERR_NUM_ERRS)
|
||||
break;
|
||||
|
||||
const Unicode::String str (Unicode::narrowToWide (infoData.m_msg));
|
||||
const std::pair<ErrorMsgMap_t::iterator, bool> retval =
|
||||
ms_errorMsgMap->insert (std::make_pair (static_cast<int>(infoData.m_type), str));
|
||||
|
||||
DEBUG_FATAL (!retval.second, ("error adding error message.\n"));
|
||||
UNREF (retval);
|
||||
}
|
||||
|
||||
ms_ERR_NO_ERROR_MSG_MSG = new String_t ((*ms_errorMsgMap)[static_cast<int>(ERR_NO_ERROR_MSG)]);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void CommandParser::deleteSubCommands ()
|
||||
{
|
||||
for (CommandParserSet_t::iterator iter = m_subCommands->begin (); iter != m_subCommands->end (); ++iter)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
|
||||
m_subCommands->clear ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
CommandParser::~CommandParser ()
|
||||
{
|
||||
m_delegate = 0;
|
||||
m_parent = 0;
|
||||
|
||||
for (CommandParserSet_t::iterator iter = m_subCommands->begin (); iter != m_subCommands->end (); ++iter)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
|
||||
m_subCommands->clear ();
|
||||
delete m_subCommands;
|
||||
m_subCommands = 0;
|
||||
|
||||
DEBUG_FATAL (ms_instanceCount == 0, ("CommandParser instanceCount went negative... bogus constructors?\n"));
|
||||
|
||||
--ms_instanceCount;
|
||||
|
||||
if (ms_instanceCount == 0)
|
||||
{
|
||||
delete ms_errorMsgMap;
|
||||
ms_errorMsgMap = 0;
|
||||
delete ms_ERR_NO_ERROR_MSG_MSG;
|
||||
ms_ERR_NO_ERROR_MSG_MSG = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void CommandParser::chopInputStrings (const String_t & str, StringVector_t & sv)
|
||||
{
|
||||
size_t pos = 0;
|
||||
size_t endpos = 0;
|
||||
Unicode::String commandPart;
|
||||
|
||||
const static Unicode::unicode_char_t sep [2] = { ';', 0 };
|
||||
|
||||
while (Unicode::getFirstToken (str, pos, endpos, commandPart, sep))
|
||||
{
|
||||
Unicode::trim (commandPart);
|
||||
|
||||
if (!commandPart.empty ())
|
||||
{
|
||||
//-- if this is the magic alias command, stop choppin
|
||||
if (isAbbrev (s_alias_cmd, commandPart) || isAbbrev (s_alias_cmd_slash, commandPart))
|
||||
{
|
||||
commandPart = str.substr (pos);
|
||||
Unicode::trim (commandPart);
|
||||
endpos = static_cast<size_t>(str.npos);
|
||||
}
|
||||
|
||||
sv.push_back (commandPart);
|
||||
}
|
||||
|
||||
if (endpos == Unicode::String::npos)
|
||||
break;
|
||||
|
||||
pos = endpos + 1;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
CommandParser::ErrorType CommandParser::parse (const NetworkId & userId, const String_t & str, String_t & result)
|
||||
{
|
||||
//----------------------------------------------------------------------
|
||||
//- first break the string into parts via semicolons, then
|
||||
//- tokenize each portion of the string.
|
||||
|
||||
ErrorType last_retval = ERR_NONE;
|
||||
|
||||
StringVector_t sv;
|
||||
|
||||
chopInputStrings (str, sv);
|
||||
|
||||
for (StringVector_t::const_iterator it = sv.begin (); it != sv.end (); ++it)
|
||||
{
|
||||
const Unicode::String & commandPart = *it;
|
||||
|
||||
if (!result.empty () && result [result.size () - 1] != '\n')
|
||||
IGNORE_RETURN (result.append (1, '\n'));
|
||||
|
||||
size_t dummy;
|
||||
StringVector_t v;
|
||||
Unicode::tokenize (commandPart, v, 0, dummy, dummy, dummy);
|
||||
|
||||
last_retval = parse (userId, v, 0, str, result);
|
||||
}
|
||||
|
||||
return last_retval;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
CommandParser * CommandParser::findParser (const StringVector_t & argv, const size_t tokenNum)
|
||||
{
|
||||
if (tokenNum >= argv.size ())
|
||||
return this;
|
||||
|
||||
// look for the appropriate subcommand
|
||||
const String_t & cur_cmd = argv [tokenNum];
|
||||
|
||||
CommandParserSet_t::iterator find_iter = std::find_if (m_subCommands->begin (), m_subCommands->end (), EqualsAbbrevNoCase (cur_cmd));
|
||||
|
||||
if (find_iter == m_subCommands->end ())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// more arguments are available, so descend the command parser tree
|
||||
|
||||
CommandParser & cmd = **find_iter;
|
||||
return cmd.findParser (argv, tokenNum + 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Note: tokenNum can exceed the capacity of argv
|
||||
* @param originalCommand
|
||||
*/
|
||||
|
||||
CommandParser::ErrorType CommandParser::parse (const NetworkId & userId, const StringVector_t & argv, const size_t tokenNum, const String_t & originalCommand, String_t & result)
|
||||
{
|
||||
// this command is a leaf node, thus it is capable of perfoming the interpret
|
||||
if (m_subCommands->size () == 0)
|
||||
{
|
||||
// performInterpret () does not get called on the root node
|
||||
if (m_parent == 0)
|
||||
{
|
||||
result += getErrorMessage (ERR_NO_NODES);
|
||||
return ERR_NO_NODES;
|
||||
}
|
||||
|
||||
// not enough arguments
|
||||
if (m_minArgs > (argv.size () - tokenNum))
|
||||
{
|
||||
result += getNotEnoughArgumentsMessage ();
|
||||
return ERR_NOT_ENOUGH_ARGUMENTS;
|
||||
}
|
||||
|
||||
//-- check for adequate permissions
|
||||
if (ms_permissionManager)
|
||||
{
|
||||
Unicode::String path;
|
||||
static const Unicode::unicode_char_t pathSep = '.';
|
||||
|
||||
const CommandParser * cmd = this;
|
||||
|
||||
while (cmd && cmd->m_parent)
|
||||
{
|
||||
if (path.empty ())
|
||||
path = cmd->getCmd ();
|
||||
else
|
||||
{
|
||||
path = cmd->getCmd () + pathSep + path;
|
||||
}
|
||||
cmd = cmd->m_parent;
|
||||
}
|
||||
|
||||
if (ms_permissionManager->isCommandAllowed (userId, path) == false)
|
||||
{
|
||||
result += getErrorMessage (getCmd (), ERR_PERMISSION_DENIED);
|
||||
return ERR_PERMISSION_DENIED;
|
||||
}
|
||||
}
|
||||
|
||||
// construct the truncated string vector the the performInterpret () method
|
||||
StringVector_t passArgv;
|
||||
passArgv.reserve (argv.size () - tokenNum + 1);
|
||||
|
||||
DEBUG_FATAL (tokenNum == 0, ("tokenNum == 0 and no subCommands -- error.\n"));
|
||||
|
||||
{
|
||||
passArgv.push_back (m_cmd);
|
||||
|
||||
for (size_t i = tokenNum; i < argv.size (); ++i)
|
||||
passArgv.push_back (argv [i]);
|
||||
}
|
||||
|
||||
CommandParser * handler = m_delegate ? m_delegate : this;
|
||||
|
||||
if (handler->performParsing(userId, passArgv, originalCommand, result, this))
|
||||
return ERR_SUCCESS;
|
||||
|
||||
return ERR_NO_HANDLER;
|
||||
}
|
||||
|
||||
// no more arguments, this is not a fully qualified command line
|
||||
if (tokenNum >= argv.size ())
|
||||
{
|
||||
|
||||
// use default command if applicable
|
||||
|
||||
CommandParserSet_t::iterator default_iter = std::find_if (m_subCommands->begin (), m_subCommands->end (), IsDefault ());
|
||||
|
||||
if (default_iter != m_subCommands->end ())
|
||||
{
|
||||
CommandParser & cmd = **default_iter;
|
||||
|
||||
// we need a modifed argument vector with the default argument on it
|
||||
StringVector_t vect = argv;
|
||||
vect.push_back (cmd.m_cmd);
|
||||
|
||||
return cmd.parse (userId, vect, tokenNum + 1, originalCommand, result);
|
||||
}
|
||||
|
||||
// list possible subcommands
|
||||
|
||||
result += getErrorMessage (constructFullPath (), ERR_NO_SUBCOMMAND_SPECIFIED);
|
||||
|
||||
showHelp (result);
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// look for the appropriate subcommand
|
||||
const String_t & cur_cmd = argv [tokenNum];
|
||||
|
||||
CommandParserSet_t::iterator find_iter = std::find_if (m_subCommands->begin (), m_subCommands->end (), EqualsAbbrevNoCase (cur_cmd));
|
||||
|
||||
if (find_iter == m_subCommands->end ())
|
||||
{
|
||||
const ErrorType etype = m_parent ? ERR_SUBCMD_NOT_FOUND : ERR_CMD_NOT_FOUND;
|
||||
result += getErrorMessage (constructFullPath (argv [tokenNum]), etype);
|
||||
return etype;
|
||||
}
|
||||
|
||||
// more arguments are available, so descend the command parser tree
|
||||
|
||||
CommandParser & cmd = **find_iter;
|
||||
return cmd.parse (userId, argv, tokenNum + 1, originalCommand, result);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
bool CommandParser::tabCompleteToken (const String_t & str, const size_t tokenPos, StringVector_t & results, size_t & token_start, size_t & token_end)
|
||||
{
|
||||
StringVector_t v;
|
||||
size_t whichToken;
|
||||
Unicode::tokenize (str, v, tokenPos, whichToken, token_start, token_end);
|
||||
|
||||
// ends with space, add an empty token
|
||||
if (whichToken == (v.size () - 1) && tokenPos > 0 && str [tokenPos-1] == ' ')
|
||||
{
|
||||
v.push_back (String_t ());
|
||||
++whichToken;
|
||||
token_start = tokenPos;
|
||||
token_end = tokenPos;
|
||||
}
|
||||
|
||||
return tabCompleteToken (v, 0, whichToken, results);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
bool CommandParser::tabCompleteToken (const StringVector_t & argv, const size_t tokenNum, const size_t whichToken, StringVector_t & results)
|
||||
{
|
||||
if (tokenNum > whichToken)
|
||||
return true;
|
||||
|
||||
// DEBUG_FATAL (argv.empty (), ("argv is empty in tab complete\n"));
|
||||
|
||||
// look for the appropriate subcommand
|
||||
const String_t empty;
|
||||
const String_t & cur_cmd = argv.empty () ? empty : argv [tokenNum];
|
||||
|
||||
// this command(s) should be under this node
|
||||
if (whichToken == tokenNum)
|
||||
{
|
||||
for (CommandParserSet_t::const_iterator iter = m_subCommands->begin (); iter != m_subCommands->end (); ++iter)
|
||||
{
|
||||
const CommandParser & sub_cmd = **iter;
|
||||
|
||||
if (sub_cmd.isAbbrev (cur_cmd))
|
||||
results.push_back (sub_cmd.m_cmd);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CommandParserSet_t::iterator find_iter = std::find_if (m_subCommands->begin (), m_subCommands->end (), EqualsAbbrevNoCase (cur_cmd));
|
||||
|
||||
if (find_iter == m_subCommands->end ())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// more arguments are available, so descend the command parser tree
|
||||
|
||||
CommandParser & cmd = **find_iter;
|
||||
return cmd.tabCompleteToken (argv, tokenNum + 1, whichToken, results);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
void CommandParser::showHelp (String_t & result) const
|
||||
{
|
||||
if (m_subCommands->size () > 0)
|
||||
{
|
||||
result +=
|
||||
Unicode::narrowToWide ("\\#ffffffCommands:\n"
|
||||
"-------------------------------------------------------\n\n");
|
||||
|
||||
if (m_parent)
|
||||
{
|
||||
result.append (m_cmd);
|
||||
result.append (Unicode::narrowToWide ("\\%030\\#00ff00"));
|
||||
result.append (m_args);
|
||||
result.append (Unicode::narrowToWide ("\\#ffffff\n\\>000"));
|
||||
result.append (m_help);
|
||||
result.append (Unicode::narrowToWide ("\\>000"));
|
||||
result.append (1, '\n');
|
||||
}
|
||||
|
||||
for (CommandParserSet_t::const_iterator iter = m_subCommands->begin (); iter != m_subCommands->end (); ++iter)
|
||||
{
|
||||
const CommandParser & sub_cmd = **iter;
|
||||
result.append (2, ' ');
|
||||
result.append (sub_cmd.m_cmd);
|
||||
result.append (Unicode::narrowToWide ("\\%030\\#00ff00"));
|
||||
result.append (sub_cmd.m_args);
|
||||
result.append (Unicode::narrowToWide ("\\#ffffff\n\\>000"));
|
||||
result.append (sub_cmd.m_help);
|
||||
result.append (Unicode::narrowToWide ("\\>000"));
|
||||
result.append (1, '\n');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result += Unicode::narrowToWide ("Usage: ");
|
||||
result.append (m_cmd);
|
||||
result.append (1, ' ');
|
||||
result.append (m_args);
|
||||
result.append (Unicode::narrowToWide (" : "));
|
||||
result.append (m_help);
|
||||
result.append (1, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
bool CommandParser::performParsing (const NetworkId & userId, const StringVector_t & argv, const String_t & originalCommand, String_t & result, const CommandParser * node)
|
||||
{
|
||||
UNREF (userId);
|
||||
UNREF (argv);
|
||||
UNREF (originalCommand);
|
||||
UNREF (node);
|
||||
|
||||
if (!result.empty () && result [result.size () - 1] != '\n')
|
||||
IGNORE_RETURN (result.append (1, '\n'));
|
||||
|
||||
result += getErrorMessage (constructFullPath (), ERR_NO_PARSER_IMPLEMENTED);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
/**
|
||||
* overwrite any existing subnode
|
||||
*/
|
||||
CommandParser * CommandParser::addSubCommand (CommandParser * node)
|
||||
{
|
||||
CommandParserSet_t::iterator find_iter = std::find_if (m_subCommands->begin (), m_subCommands->end (), EqualsCmdString (node->m_cmd));
|
||||
|
||||
// remove existing
|
||||
if (find_iter != m_subCommands->end ())
|
||||
{
|
||||
delete *find_iter;
|
||||
m_subCommands->erase (find_iter);
|
||||
}
|
||||
|
||||
std::pair<CommandParserSet_t::iterator, bool> retval = m_subCommands->insert (node);
|
||||
|
||||
DEBUG_FATAL (retval.second == false, ("Error in command parser.\n"));
|
||||
UNREF (retval);
|
||||
|
||||
node->m_parent = this;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
bool CommandParser::removeParser (CommandParser * const parser)
|
||||
{
|
||||
CommandParserSet_t::iterator iter = m_subCommands->find (parser);
|
||||
|
||||
if (iter == m_subCommands->end ())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_subCommands->erase (iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
const CommandParser::String_t & CommandParser::getErrorMessage (CommandParser::ErrorType code) const
|
||||
{
|
||||
ErrorMsgMap_t::const_iterator iter = ms_errorMsgMap->find (static_cast<int>(code));
|
||||
|
||||
if (iter == ms_errorMsgMap->end ())
|
||||
{
|
||||
return *ms_ERR_NO_ERROR_MSG_MSG;
|
||||
}
|
||||
else
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
CommandParser::String_t CommandParser::getErrorMessage (const CommandParser::String_t & prefix, CommandParser::ErrorType code) const
|
||||
{
|
||||
return prefix + Unicode::narrowToWide (": ") + getErrorMessage (code);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
CommandParser::String_t CommandParser::getFullErrorMessage (CommandParser::ErrorType code) const
|
||||
{
|
||||
return getErrorMessage (constructFullPath (), code);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
CommandParser::String_t CommandParser::getNotEnoughArgumentsMessage (void) const
|
||||
{
|
||||
return (constructFullPath () + Unicode::narrowToWide(": ") + getErrorMessage (ERR_NOT_ENOUGH_ARGUMENTS) + Unicode::narrowToWide ("\nUsage: ") + m_cmd).append (1, ' ') + m_args;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
/**
|
||||
* createDelegateCommands takes an array of CmdInfo objects, terminated with a CmdInfo with an empty m_cmd
|
||||
*/
|
||||
|
||||
void CommandParser::createDelegateCommands (const CmdInfo cmds[])
|
||||
{
|
||||
for (int i = 0; ; ++i)
|
||||
{
|
||||
const CommandParser::CmdInfo & info = cmds [i];
|
||||
|
||||
if (*info.m_cmd == 0)
|
||||
break;
|
||||
|
||||
addSubCommand (new CommandParser (info, this));
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
bool CommandParser::isAbbrev (const String_t & str, const String_t & wholeStr)
|
||||
{
|
||||
if (wholeStr.length () < str.length ())
|
||||
return false;
|
||||
|
||||
if (str.empty ())
|
||||
return true;
|
||||
|
||||
return Unicode::caseInsensitiveCompare (str, wholeStr, 0, str.length ());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void CommandParser::reconstructString (const StringVector_t & args, size_t startToken, size_t endToken, bool quote, Unicode::String & result)
|
||||
{
|
||||
endToken = std::min (endToken, args.size ());
|
||||
|
||||
result.clear ();
|
||||
|
||||
for (size_t i = startToken; i < endToken; ++i)
|
||||
{
|
||||
if (i != startToken)
|
||||
result.append (1, ' ');
|
||||
|
||||
const Unicode::String & str = args [i];
|
||||
|
||||
if (quote && str.find ('\"') != str.npos)
|
||||
{
|
||||
result.append (1, '\"');
|
||||
result += str;
|
||||
result.append (1, '\"');
|
||||
}
|
||||
else
|
||||
result += str;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
CommandParser::String_t CommandParser::constructFullPath (const String_t & subCmd) const
|
||||
{
|
||||
String_t p (constructFullPath());
|
||||
|
||||
if (!subCmd.empty ())
|
||||
{
|
||||
if (!p.empty ())
|
||||
p.append (1, ' ');
|
||||
|
||||
p.append (subCmd);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
CommandParser::String_t CommandParser::constructFullPath () const
|
||||
{
|
||||
String_t p;
|
||||
|
||||
if (m_parent)
|
||||
p = m_parent->constructFullPath();
|
||||
|
||||
if (!p.empty ())
|
||||
p.append (1, ' ');
|
||||
|
||||
p.append (m_cmd);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//-- this method is very inefficient
|
||||
//
|
||||
|
||||
bool CommandParser::isAbbrev (const String_t & str, const char * const wholeWord)
|
||||
{
|
||||
return isAbbrev (str, Unicode::narrowToWide (wholeWord));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
bool CommandParser::isCommand (const String_t & str, const char * cmd)
|
||||
{
|
||||
return str == Unicode::narrowToWide (cmd);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
CommandParser * CommandParser::getDelegate() const
|
||||
{
|
||||
return m_delegate;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,347 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CommandParser.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// jwatson
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_CommandParser_H
|
||||
#define INCLUDED_CommandParser_H
|
||||
|
||||
#include "Unicode.h"
|
||||
|
||||
class CommandPermissionManager;
|
||||
class NetworkId;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
/**
|
||||
* CommandParser is a generic class for parsing command lines.
|
||||
* A CommandParser instance is simply a node in a hierarchical tree of
|
||||
* commands and subcommands.
|
||||
*
|
||||
* A command node may be constructed in 2 ways:
|
||||
*
|
||||
* 1. Subclass the CommandParser to handle the command. The command is handled
|
||||
* by the performParsing () method, which subclasses should ovverride. Attach
|
||||
* an instance of your subclass to the appropriate node of your command tree.
|
||||
*
|
||||
* 2. Simply create an instance of CommandParser, with its delegate set to be
|
||||
* any other CommandParser instance. The delegate's performParsing () will
|
||||
* get called when your new command gets invoked. argv[0] in performParsing
|
||||
* will be the command that corresponds to your new node. This technique is
|
||||
* useful for adding small, lightweight subcommands to a command node, where
|
||||
* creating subclasses would be overkill and annoying.
|
||||
*
|
||||
* performParsing () is the only method that must be overridden by subclasses.
|
||||
*
|
||||
* One of the parse () methods and one of the tabCompleTokens () are the entry
|
||||
* points into the tree to parse a command or tab complete a command, respectively.
|
||||
*
|
||||
* Examples of how to use this system may be found in the SWUI project.
|
||||
*
|
||||
*/
|
||||
|
||||
class CommandParser
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Unicode::String String_t;
|
||||
typedef stdvector<String_t>::fwd StringVector_t;
|
||||
|
||||
enum ErrorType
|
||||
{
|
||||
ERR_NONE,
|
||||
ERR_SUCCESS,
|
||||
ERR_FAIL,
|
||||
ERR_NO_ERROR_MSG,
|
||||
ERR_CMD_NOT_FOUND,
|
||||
ERR_SUBCMD_NOT_FOUND,
|
||||
ERR_NO_HANDLER,
|
||||
ERR_NO_SCENE,
|
||||
ERR_SCENE_INVALID_OPERATION,
|
||||
ERR_NO_AVATAR,
|
||||
ERR_NO_CONTROLLER,
|
||||
ERR_INVALID_ARGUMENTS,
|
||||
ERR_NOT_ENOUGH_ARGUMENTS,
|
||||
ERR_SENDING_COMMAND_TO_SERVER,
|
||||
ERR_NO_NODES,
|
||||
ERR_NO_SUBCOMMAND_SPECIFIED,
|
||||
ERR_NO_PARSER_IMPLEMENTED,
|
||||
ERR_INVALID_OBJECT,
|
||||
ERR_INVALID_SCRIPT,
|
||||
ERR_INVALID_TRIGGER,
|
||||
ERR_NOT_SKUFREE_TEMPLATE,
|
||||
ERR_SCRIPT_CONTINUE,
|
||||
ERR_SCRIPT_OVERRIDE,
|
||||
ERR_UNSUPPORTED_TRIGGER,
|
||||
ERR_INVALID_PARAMETER_COUNT,
|
||||
ERR_INVALID_OBJVAR,
|
||||
ERR_LIST_OBJVAR_NOT_SUPPORTED,
|
||||
ERR_INVALID_INT_OBJVAR,
|
||||
ERR_INVALID_REAL_OBJVAR,
|
||||
ERR_PERMISSION_DENIED,
|
||||
ERR_NO_TERRAIN,
|
||||
ERR_TERRAIN_GENERATION,
|
||||
ERR_INVALID_USER,
|
||||
ERR_NO_USER_OBJECT,
|
||||
ERR_NO_TARGET_OBJECT,
|
||||
ERR_BAD_ATTACKER,
|
||||
ERR_BAD_DEFENDER,
|
||||
ERR_QUEUE_COMMAND_FAIL,
|
||||
ERR_CANNOT_XFER_AUTH,
|
||||
ERR_INVALID_TEMPLATE,
|
||||
ERR_INVALID_CONTAINER_TRANSFER,
|
||||
ERR_FILE_NOT_FOUND,
|
||||
ERR_INVALID_INGREDIENT,
|
||||
ERR_INVALID_STATION,
|
||||
ERR_STATION_IN_USE,
|
||||
ERR_FILLSLOT_FAIL,
|
||||
ERR_CUSTOMIZE_FAIL,
|
||||
ERR_TEMPLATE_NOT_LOADED,
|
||||
ERR_ACTIVE_MANF_STATION,
|
||||
ERR_SCRIPTING_ENABLED,
|
||||
ERR_SCRIPTING_DISABLED,
|
||||
|
||||
|
||||
ERR_NUM_ERRS
|
||||
};
|
||||
|
||||
struct ErrorInfoData
|
||||
{
|
||||
ErrorType m_type;
|
||||
const char * m_msg;
|
||||
};
|
||||
|
||||
struct CmdInfo
|
||||
{
|
||||
const char * m_cmd;
|
||||
size_t m_minArgs;
|
||||
const char * m_args;
|
||||
const char * m_help;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
CommandParser (const CmdInfo & info, CommandParser * delegate);
|
||||
CommandParser (const String_t & cmd, size_t minArgs, const String_t & args, const String_t & help, CommandParser * delegate);
|
||||
CommandParser (const char * cmd, size_t minArgs, const char * args, const char * help, CommandParser * delegate);
|
||||
virtual ~CommandParser ();
|
||||
|
||||
const String_t & getCmd () const;
|
||||
const String_t & getArgs () const;
|
||||
const String_t & getHelp () const;
|
||||
const size_t getMinArgs () const;
|
||||
|
||||
ErrorType parse (const NetworkId & userId, const String_t & str, String_t & result);
|
||||
|
||||
ErrorType parse (const NetworkId & userId, const StringVector_t & argv, size_t tokenNum, const String_t & originalCommand, String_t & result);
|
||||
|
||||
bool tabCompleteToken (const String_t & str, size_t tokenPos, StringVector_t & results, size_t & token_start, size_t & token_end);
|
||||
bool tabCompleteToken (const StringVector_t & argv, size_t tokenNum, size_t whichToken, StringVector_t & results);
|
||||
|
||||
virtual bool performParsing (const NetworkId & userId, const StringVector_t & argv, const String_t & originalCommand, String_t & result, const CommandParser * node);
|
||||
|
||||
void showHelp (String_t & result) const;
|
||||
|
||||
CommandParser * addSubCommand (CommandParser * node);
|
||||
|
||||
bool isAbbrev (const String_t & str) const;
|
||||
|
||||
const String_t & getErrorMessage (ErrorType code) const;
|
||||
String_t getErrorMessage (const String_t & prefix, ErrorType code) const;
|
||||
String_t getFullErrorMessage (ErrorType code) const;
|
||||
String_t getNotEnoughArgumentsMessage () const;
|
||||
bool isDefault () const;
|
||||
void setDefault (bool b);
|
||||
|
||||
static bool isAbbrev (const String_t & str, const String_t & wholeWord);
|
||||
static bool isAbbrev (const String_t & str, const char * wholeWord);
|
||||
|
||||
static bool isCommand (const String_t & str, const char * cmd);
|
||||
|
||||
static void setPermissionManager (const CommandPermissionManager * permissionManager);
|
||||
|
||||
static void reconstructString (const StringVector_t & args, size_t startToken, size_t endToken, bool quote, Unicode::String & result);
|
||||
|
||||
static void chopInputStrings (const String_t & str, StringVector_t & sv);
|
||||
|
||||
String_t constructFullPath () const;
|
||||
String_t constructFullPath (const String_t & subCmd) const;
|
||||
|
||||
CommandParser * getDelegate() const;
|
||||
|
||||
CommandParser * findParser (const StringVector_t & argv, size_t tokenNum);
|
||||
|
||||
protected:
|
||||
|
||||
void createDelegateCommands (const CmdInfo cmds[]);
|
||||
bool removeParser (CommandParser * parser);
|
||||
void deleteSubCommands ();
|
||||
|
||||
private:
|
||||
CommandParser ();
|
||||
CommandParser (const CommandParser & rhs);
|
||||
CommandParser & operator= (const CommandParser & rhs);
|
||||
|
||||
static void initStatics ();
|
||||
|
||||
private:
|
||||
|
||||
String_t m_cmd;
|
||||
size_t m_minArgs;
|
||||
String_t m_args;
|
||||
String_t m_help;
|
||||
bool m_default;
|
||||
|
||||
const CommandParser * m_parent;
|
||||
CommandParser * m_delegate;
|
||||
|
||||
typedef stdmap<int, String_t>::fwd ErrorMsgMap_t;
|
||||
|
||||
static size_t ms_instanceCount;
|
||||
static String_t * ms_ERR_NO_ERROR_MSG_MSG;
|
||||
static ErrorMsgMap_t * ms_errorMsgMap;
|
||||
|
||||
const static CommandPermissionManager * ms_permissionManager;
|
||||
|
||||
/**
|
||||
* Comparator for sorting the set of commands
|
||||
*/
|
||||
|
||||
struct Comparator
|
||||
{
|
||||
bool operator () (const CommandParser * a, const CommandParser * b) const;
|
||||
};
|
||||
|
||||
typedef stdset<CommandParser*, Comparator>::fwd CommandParserSet_t;
|
||||
|
||||
CommandParserSet_t * m_subCommands;
|
||||
|
||||
/**
|
||||
* Predicate for searching for a command by abbreviation.
|
||||
*/
|
||||
|
||||
struct EqualsAbbrevNoCase
|
||||
{
|
||||
const String_t & m_str;
|
||||
|
||||
explicit EqualsAbbrevNoCase (const String_t & theStr) : m_str (theStr) {}
|
||||
|
||||
inline bool operator() (const CommandParser * t) const
|
||||
{
|
||||
return t->isAbbrev (m_str);
|
||||
}
|
||||
|
||||
EqualsAbbrevNoCase (const EqualsAbbrevNoCase & rhs) : m_str (rhs.m_str) {}
|
||||
|
||||
private:
|
||||
EqualsAbbrevNoCase & operator= (const EqualsAbbrevNoCase & rhs); //lint !e754
|
||||
EqualsAbbrevNoCase ();
|
||||
};
|
||||
|
||||
/**
|
||||
* Predicate for searching for a command by full name.
|
||||
*/
|
||||
|
||||
struct EqualsCmdString
|
||||
{
|
||||
const String_t & m_str;
|
||||
|
||||
explicit EqualsCmdString (const String_t & theStr) : m_str (theStr) {}
|
||||
|
||||
inline bool operator() (const CommandParser * t) const
|
||||
{
|
||||
return t->getCmd () == m_str;
|
||||
}
|
||||
|
||||
EqualsCmdString (const EqualsCmdString & rhs) : m_str (rhs.m_str) {}
|
||||
|
||||
private:
|
||||
EqualsCmdString & operator= (const EqualsCmdString & rhs); //lint !e754
|
||||
EqualsCmdString ();
|
||||
};
|
||||
|
||||
/**
|
||||
* Predicate for searching for a default command.
|
||||
*/
|
||||
|
||||
struct IsDefault
|
||||
{
|
||||
inline bool operator() (const CommandParser * t) const
|
||||
{
|
||||
return t->isDefault ();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// ======================================================================
|
||||
|
||||
|
||||
inline const CommandParser::String_t & CommandParser::getCmd () const
|
||||
{
|
||||
return m_cmd;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline const CommandParser::String_t & CommandParser::getArgs () const
|
||||
{
|
||||
return m_args;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline const CommandParser::String_t & CommandParser::getHelp () const
|
||||
{
|
||||
return m_help;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline const size_t CommandParser::getMinArgs () const
|
||||
{
|
||||
return m_minArgs;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline bool CommandParser::isDefault () const
|
||||
{
|
||||
return m_default;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline void CommandParser::setDefault (const bool b)
|
||||
{
|
||||
m_default = b;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline bool CommandParser::Comparator::operator () (const CommandParser * a, const CommandParser * b) const
|
||||
{
|
||||
return a->getCmd () < b->getCmd ();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline bool CommandParser::isAbbrev (const String_t & abbrev) const
|
||||
{
|
||||
return isAbbrev (abbrev, m_cmd);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline void CommandParser::setPermissionManager (const CommandPermissionManager * permissionManager)
|
||||
{
|
||||
ms_permissionManager = permissionManager;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,110 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CommandParserHistory.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedCommandParser/FirstSharedCommandParser.h"
|
||||
#include "sharedCommandParser/CommandParserHistory.h"
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
CommandParserHistory::CommandParserHistory () :
|
||||
m_index (-1),
|
||||
m_history (NON_NULL (new HistoryList_t)),
|
||||
m_maxSize (50)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
CommandParserHistory::~CommandParserHistory ()
|
||||
{
|
||||
delete m_history;
|
||||
m_history = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
bool CommandParserHistory::back (Unicode::String & result)
|
||||
{
|
||||
if (static_cast<size_t> (m_index + 1) >= m_history->size ())
|
||||
return false;
|
||||
|
||||
++m_index;
|
||||
|
||||
result = (*m_history) [static_cast<size_t> (m_index)];
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
bool CommandParserHistory::forward (Unicode::String & result)
|
||||
{
|
||||
if (m_index - 1 < -1)
|
||||
return false;
|
||||
|
||||
if (--m_index < 0)
|
||||
return false;
|
||||
|
||||
result = (*m_history) [static_cast<size_t> (m_index)];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
void CommandParserHistory::push (const Unicode::String & cmd)
|
||||
{
|
||||
//-- don't push identical commands back-to-back
|
||||
if (!m_history->empty ())
|
||||
{
|
||||
if (m_history->front () == cmd)
|
||||
{
|
||||
m_index = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_history->push_front (cmd);
|
||||
if (m_history->size () > m_maxSize)
|
||||
m_history->pop_back ();
|
||||
|
||||
m_index = -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
bool CommandParserHistory::getHistoryCommandByAbbrev (const Unicode::String & abbrev, Unicode::String & cmd) const
|
||||
{
|
||||
const size_t len = abbrev.length ();
|
||||
const HistoryList_t::const_iterator end = m_history->end ();
|
||||
|
||||
for (HistoryList_t::const_iterator it = m_history->begin (); it != end; ++it)
|
||||
{
|
||||
if ((*it).compare (0, len, abbrev) == 0)
|
||||
{
|
||||
cmd = (*it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
bool CommandParserHistory::front (Unicode::String & cmd)
|
||||
{
|
||||
if (m_history->empty ())
|
||||
return false;
|
||||
|
||||
cmd = (*m_history) [0];
|
||||
return true;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,75 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CommandParserHistory.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_CommandParserHistory_H
|
||||
#define INCLUDED_CommandParserHistory_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class CommandParserHistory
|
||||
{
|
||||
public:
|
||||
|
||||
typedef stddeque<Unicode::String>::fwd HistoryList_t;
|
||||
|
||||
CommandParserHistory ();
|
||||
~CommandParserHistory ();
|
||||
|
||||
bool back (Unicode::String & result);
|
||||
bool forward (Unicode::String & result);
|
||||
|
||||
size_t getMaxSize () const;
|
||||
void setMaxSize (size_t newSize);
|
||||
void resetIndex ();
|
||||
|
||||
void push (const Unicode::String & cmd);
|
||||
bool front (Unicode::String & cmd);
|
||||
|
||||
const HistoryList_t & getHistoryList () const;
|
||||
|
||||
bool getHistoryCommandByAbbrev (const Unicode::String & abbrev, Unicode::String & cmd) const;
|
||||
|
||||
|
||||
private:
|
||||
CommandParserHistory (const CommandParserHistory & rhs);
|
||||
CommandParserHistory & operator= (const CommandParserHistory & rhs);
|
||||
|
||||
private:
|
||||
|
||||
/** -1 means no index into history, 0 is most recent command */
|
||||
|
||||
int m_index;
|
||||
HistoryList_t * m_history;
|
||||
size_t m_maxSize;
|
||||
|
||||
};
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline size_t CommandParserHistory::getMaxSize (void) const
|
||||
{
|
||||
return m_maxSize;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
inline void CommandParserHistory::setMaxSize (const size_t size)
|
||||
{
|
||||
m_maxSize = size;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
inline void CommandParserHistory::resetIndex (void)
|
||||
{
|
||||
m_index = -1;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline const CommandParserHistory::HistoryList_t & CommandParserHistory::getHistoryList () const
|
||||
{
|
||||
NOT_NULL (m_history);
|
||||
return *m_history;
|
||||
}
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CommandPermissionManager.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedCommandParser/FirstSharedCommandParser.h"
|
||||
#include "sharedCommandParser/CommandPermissionManager.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
CommandPermissionManager::CommandPermissionManager ()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
CommandPermissionManager::~CommandPermissionManager ()
|
||||
{
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,34 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CommandPermissionManager.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_CommandPermissionManager_H
|
||||
#define INCLUDED_CommandPermissionManager_H
|
||||
|
||||
class NetworkId;
|
||||
|
||||
// ======================================================================
|
||||
class CommandPermissionManager
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~CommandPermissionManager () = 0;
|
||||
|
||||
/**
|
||||
* the commandPath is a period-seperated path down through the command tree
|
||||
*/
|
||||
|
||||
virtual bool isCommandAllowed (const NetworkId & userId, const Unicode::String & commandPath) const = 0;
|
||||
|
||||
protected:
|
||||
CommandPermissionManager ();
|
||||
CommandPermissionManager (const CommandPermissionManager & rhs);
|
||||
CommandPermissionManager & operator= (const CommandPermissionManager & rhs);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,17 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FirstCommandParser.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_FirstCommandParser_H
|
||||
#define INCLUDED_FirstCommandParser_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FirstCommandParser.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedCommandParser/FirstSharedCommandParser.h"
|
||||
Reference in New Issue
Block a user