[base] introduce a command type that gets registered with the app

This commit is contained in:
Joe Thornber
2016-01-08 12:51:52 +00:00
parent a709b9718b
commit c93e728ef4
28 changed files with 776 additions and 411 deletions

View File

@@ -1,14 +1,47 @@
#include "base/application.h"
#include <boost/lexical_cast.hpp>
#include <libgen.h>
#include <linux/limits.h>
#include <string.h>
#include <stdlib.h>
using namespace base;
using namespace boost;
using namespace std;
//----------------------------------------------------------------
command::command(string const &name)
: name_(name) {
}
void
command::die(string const &msg)
{
cerr << msg << endl;
usage(cerr);
exit(1);
}
uint64_t
command::parse_uint64(string const &str, string const &desc)
{
try {
// FIXME: check trailing garbage is handled
return lexical_cast<uint64_t>(str);
} catch (...) {
ostringstream out;
out << "Couldn't parse " << desc << ": '" << str << "'";
die(out.str());
}
return 0; // never get here
}
//----------------------------------------------------------------
int
application::run(int argc, char **argv)
{
@@ -26,7 +59,7 @@ application::run(int argc, char **argv)
cmd = argv[0];
}
std::list<command const *>::const_iterator it;
std::list<command::ptr>::const_iterator it;
for (it = cmds_.begin(); it != cmds_.end(); ++it) {
if (cmd == (*it)->get_name())
return (*it)->run(argc, argv);
@@ -43,7 +76,7 @@ application::usage()
std::cerr << "Usage: <command> <args>\n"
<< "commands:\n";
std::list<command const *>::const_iterator it;
std::list<command::ptr>::const_iterator it;
for (it = cmds_.begin(); it != cmds_.end(); ++it) {
std::cerr << " " << (*it)->get_name() << "\n";
}

View File

@@ -1,40 +1,60 @@
#ifndef BASE_APPLICATION_H
#define BASE_APPLICATION_H
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <list>
#include <string>
#include <stdexcept>
#include <stdint.h>
//----------------------------------------------------------------
namespace base {
class command {
public:
typedef int (*cmd_fn)(int, char **);
typedef boost::shared_ptr<command> ptr;
command(std::string const &name, cmd_fn fn)
: name_(name),
fn_(fn) {
}
command(std::string const &name);
virtual ~command() {}
void die(std::string const &msg);
uint64_t parse_uint64(std::string const &str, std::string const &desc);
virtual void usage(std::ostream &out) const = 0;
virtual int run(int argc, char **argv) = 0;
std::string const &get_name() const {
return name_;
}
private:
std::string name_;
};
class command_old : public command {
public:
typedef int (*cmd_fn)(int, char **);
command_old(std::string const &name, cmd_fn fn)
: command(name),
fn_(fn) {
}
int run(int argc, char **argv) const {
return fn_(argc, argv);
}
private:
std::string name_;
cmd_fn fn_;
};
class application {
public:
void add_cmd(command const &c) {
cmds_.push_back(&c);
void add_cmd(command::ptr c) {
cmds_.push_back(c);
}
int run(int argc, char **argv);
@@ -43,7 +63,7 @@ namespace base {
void usage();
std::string get_basename(std::string const &path) const;
std::list<command const *> cmds_;
std::list<command::ptr> cmds_;
};
}