Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cmd/traffic_cache_tool/CacheTool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,7 @@ struct option Options[] = {{"help", 0, nullptr, 'h'},
}

Errata
List_Stripes(Cache::SpanDumpDepth depth, int argc, char *argv[])
List_Stripes(Cache::SpanDumpDepth depth)
{
Errata zret;
Cache cache;
Expand Down Expand Up @@ -1241,9 +1241,9 @@ main(int argc, char *argv[])

Commands
.add("list", "List elements of the cache",
[](int argc, char *argv[]) { return List_Stripes(Cache::SpanDumpDepth::SPAN, argc, argv); })
[]() { return List_Stripes(Cache::SpanDumpDepth::SPAN); })
.subCommand(std::string("stripes"), std::string("List the stripes"),
[](int argc, char *argv[]) { return List_Stripes(Cache::SpanDumpDepth::STRIPE, argc, argv); });
[]() { return List_Stripes(Cache::SpanDumpDepth::STRIPE); });
Commands.add(std::string("clear"), std::string("Clear spans"), &Clear_Spans);
Commands.add(std::string("volumes"), std::string("Volumes"), &Simulate_Span_Allocation);
Commands.add(std::string("alloc"), std::string("Storage allocation"))
Expand Down
51 changes: 31 additions & 20 deletions cmd/traffic_cache_tool/Command.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,37 +42,45 @@ ERR_COMMAND_TAG_NOT_FOUND(char const *tag)
return ts::Errata(s.str());
}

CommandTable::Command::Command()
CommandTable::Command::Command() {}

CommandTable::Command::Command(std::string const &name, std::string const &help) : _name(name), _help(help)
{
}

CommandTable::Command::Command(std::string const &name, std::string const &help) : _name(name), _help(help)
CommandTable::Command::Command(std::string const &name, std::string const &help, LeafAction const &f)
: _name(name), _help(help)
{
_action = f;
}

CommandTable::Command::Command(std::string const &name, std::string const &help, CommandFunction const &f)
: _name(name), _help(help), _func(f)
CommandTable::Command::Command(std::string const &name, std::string const &help, NullaryAction const &f)
: _name(name), _help(help)
{
_action = f;
}

auto
CommandTable::Command::set(CommandFunction const &f) -> self &
CommandTable::Command::~Command() {
}

CommandTable::Command &
CommandTable::Command::subCommand(std::string const &name, std::string const &help, LeafAction const &f)
{
_func = f;
return *this;
_group.push_back(Command(name, help, f));
return _group.back();
}

CommandTable::Command &
CommandTable::Command::subCommand(std::string const &name, std::string const &help, CommandFunction const &f)
CommandTable::Command::subCommand(std::string const &name, std::string const &help, NullaryAction const &f)
{
_group.emplace_back(Command(name, help, f));
_group.push_back(Command(name, help, f));
return _group.back();
}

auto
CommandTable::Command::subCommand(std::string const &name, std::string const &help) -> self &
{
_group.emplace_back(Command(name, help));
_group.push_back(Command(name, help));
return _group.back();
}

Expand All @@ -81,10 +89,11 @@ CommandTable::Command::invoke(int argc, char *argv[])
{
ts::Errata zret;

if (CommandTable::_opt_idx >= argc || argv[CommandTable::_opt_idx][0] == '-') {
// Tail of command keywords, try to invoke.
if (_func) {
zret = _func(argc - CommandTable::_opt_idx, argv + CommandTable::_opt_idx);
if (_action.is_leaf()) {
zret = _action.invoke(argc - CommandTable::_opt_idx, argv + CommandTable::_opt_idx);
} else if (CommandTable::_opt_idx >= argc || argv[CommandTable::_opt_idx][0] == '-') {
if (_action.is_nullary()) {
zret = _action.invoke();
} else {
std::ostringstream s;
s << "Incomplete command, additional keyword required";
Expand Down Expand Up @@ -132,10 +141,6 @@ CommandTable::Command::helpMessage(int argc, char *argv[], std::ostream &out, st
}
}

CommandTable::Command::~Command()
{
}

CommandTable::CommandTable()
{
}
Expand All @@ -147,7 +152,13 @@ CommandTable::add(std::string const &name, std::string const &help) -> Command &
}

auto
CommandTable::add(std::string const &name, std::string const &help, CommandFunction const &f) -> Command &
CommandTable::add(std::string const &name, std::string const &help, LeafAction const &f) -> Command &
{
return _top.subCommand(name, help, f);
}

auto
CommandTable::add(std::string const &name, std::string const &help, NullaryAction const &f) -> Command &
{
return _top.subCommand(name, help, f);
}
Expand Down
89 changes: 81 additions & 8 deletions cmd/traffic_cache_tool/Command.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <functional>
#include <string>
#include <iostream>
#include <memory.h>
#include <tsconfig/Errata.h>

#if !defined(CACHE_TOOL_COMMAND_H)
Expand All @@ -44,8 +45,10 @@ class CommandTable
{
typedef CommandTable self; ///< Self reference type.
public:
/// Signature for actual command implementation.
typedef std::function<ts::Errata(int argc, char *argv[])> CommandFunction;
/// Signature for a leaf command.
using LeafAction = std::function<ts::Errata(int argc, char *argv[])>;
/// Signature for a argumentless command.
using NullaryAction = std::function<ts::Errata ()>;

CommandTable();

Expand All @@ -56,6 +59,7 @@ class CommandTable
{
typedef Command self; ///< Self reference type.
public:
Command(Command && that) = default;
~Command();

/** Add a subcommand to this command.
Expand All @@ -65,11 +69,11 @@ class CommandTable
/** Add a subcommand to this command.
@return The new sub command instance.
*/
Command &subCommand(std::string const &name, std::string const &help, CommandFunction const &f);
Command &subCommand(std::string const &name, std::string const &help, NullaryAction const &f);
/** Add a leaf command.
@return This new sub command instance.
*/
Command &set(CommandFunction const &f);
Command &subCommand(std::string const &name, std::string const &help, LeafAction const &f);

/** Invoke a command.
@return The return value of the executed command, or an error value if the command was not found.
Expand All @@ -83,8 +87,70 @@ class CommandTable

std::string _name; ///< Command name.
std::string _help; ///< Help message.
/// Command to execute if no more keywords.
CommandFunction _func;

/** Class to hold varying types of functions.

@internal A bit ugly, I need to do better wrapping and type erasure.
*/
class Action {
public:
/// Type of the function stored.
enum Type {
NIL, ///< Nothing / empty
LEAF, ///< Leaf action (arguments)
NULLARY, ///< Nullary action.
};
Action() { }
Action(Action && that) {
_type = that._type;
memcpy(_data, that._data, sizeof(_data));
that._type = NIL;
}
~Action() { this->clear(); }

Action& operator = (LeafAction const& a) {
this->clear();
_type = LEAF;
new (_data) LeafAction(a);
return *this;
}

Action& operator = (NullaryAction const& a) {
this->clear();
_type = NULLARY;
new (_data) NullaryAction(a);
return *this;
}

Errata invoke(int argc, char *argv[]) {
assert(LEAF == _type);
return (*reinterpret_cast<LeafAction*>(_data))(argc, argv);
}

Errata invoke() {
assert(NULLARY == _type);
return (*reinterpret_cast<NullaryAction*>(_data))();
}

bool is_leaf() const { return LEAF == _type; }
bool is_nullary() const { return NULLARY == _type; }

protected:

void clear() {
switch (_type) {
case NIL: break;
case LEAF: reinterpret_cast<LeafAction*>(_data)->~LeafAction(); break;
case NULLARY: reinterpret_cast<NullaryAction*>(_data)->~NullaryAction(); break;
}
_type = NIL;
}

Type _type = NIL; ///< Type of function stored.
/// Raw storage for the function.
char _data[sizeof(NullaryAction) > sizeof(LeafAction) ? sizeof(NullaryAction) : sizeof(LeafAction)];
} _action;

/// Next command for current keyword.
CommandGroup _group;

Expand All @@ -93,15 +159,22 @@ class CommandTable
/// Construct with a function for this command.
Command(std::string const &name, std::string const &help);
/// Construct with a function for this command.
Command(std::string const &name, std::string const &help, CommandFunction const &f);
Command(std::string const &name, std::string const &help, LeafAction const &f);
/// Construct with a function for this command.
Command(std::string const &name, std::string const &help, NullaryAction const &f);

friend class CommandTable;
};

/** Add a direct command.
@return The created @c Command instance.
*/
Command &add(std::string const &name, std::string const &help, CommandFunction const &f);
Command &add(std::string const &name, std::string const &help, LeafAction const &f);

/** Add a direct command.
@return The created @c Command instance.
*/
Command &add(std::string const &name, std::string const &help, NullaryAction const &f);

/** Add a parent command.
@return The created @c Command instance.
Expand Down