Finish phonebook command and add to install targets.
This commit is contained in:
parent
30c586d37d
commit
e3c95964b3
10
Arena.cc
10
Arena.cc
|
@ -123,25 +123,27 @@ Arena::Open(const char *path)
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
Arena::Create(const char *path, size_t fileSize, mode_t mode)
|
Arena::Create(const char *path, size_t fileSize)
|
||||||
{
|
{
|
||||||
|
FILE *fHandle = nullptr;
|
||||||
int newFileDes = 0;
|
int newFileDes = 0;
|
||||||
|
|
||||||
if (this->size > 0) {
|
if (this->size > 0) {
|
||||||
this->Destroy();
|
this->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
newFileDes = open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
|
|
||||||
if (newFileDes == -1) {
|
fHandle = fopen(path, "w");
|
||||||
|
if (fHandle == nullptr) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
newFileDes = fileno(fHandle);
|
||||||
|
|
||||||
if (ftruncate(newFileDes, fileSize) == -1) {
|
if (ftruncate(newFileDes, fileSize) == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(newFileDes);
|
close(newFileDes);
|
||||||
|
|
||||||
return this->Open(path);
|
return this->Open(path);
|
||||||
}
|
}
|
||||||
#elif defined(__WIN64__) || defined(__WIN32__) || defined(WIN32)
|
#elif defined(__WIN64__) || defined(__WIN32__) || defined(WIN32)
|
||||||
|
|
16
Arena.h
16
Arena.h
|
@ -35,15 +35,6 @@
|
||||||
|
|
||||||
namespace klib {
|
namespace klib {
|
||||||
|
|
||||||
/// DefaultFileMode is a sane set of default permissions that can be used for a
|
|
||||||
/// new Arena.
|
|
||||||
#if defined(__linux__)
|
|
||||||
static constexpr mode_t DefaultFileMode = 0644;
|
|
||||||
#elif defined(__WIN64__) || defined(__WIN32__) || defined(WIN32)
|
|
||||||
static constexpr DWORD DefaultFileMode =
|
|
||||||
(FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/// \enum ArenaType
|
/// \enum ArenaType
|
||||||
///
|
///
|
||||||
|
@ -126,10 +117,9 @@ public:
|
||||||
///
|
///
|
||||||
/// \param path The path to the file that should be created.
|
/// \param path The path to the file that should be created.
|
||||||
/// \param fileSize The size of the file to create.
|
/// \param fileSize The size of the file to create.
|
||||||
/// \param mode The permissions to load.
|
|
||||||
/// \return Returns 0 on success and -1 on error.
|
/// \return Returns 0 on success and -1 on error.
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
int Create(const char *path, size_t fileSize, mode_t mode);
|
int Create(const char *path, size_t fileSize);
|
||||||
#elif defined(__WIN64__) || defined(__WIN32__) || defined(WIN32)
|
#elif defined(__WIN64__) || defined(__WIN32__) || defined(WIN32)
|
||||||
|
|
||||||
int Create(const char *path, size_t fileSize, DWORD mode);
|
int Create(const char *path, size_t fileSize, DWORD mode);
|
||||||
|
@ -144,11 +134,7 @@ public:
|
||||||
///
|
///
|
||||||
/// \param path The path to the file to be loaded.
|
/// \param path The path to the file to be loaded.
|
||||||
/// \return Returns 0 on success and -1 on error.
|
/// \return Returns 0 on success and -1 on error.
|
||||||
#if defined(__linux__)
|
|
||||||
int Open(const char *path);
|
int Open(const char *path);
|
||||||
#elif defined(__WIN64__) || defined(__WIN32__) || defined(WIN32)
|
|
||||||
int Open(const char *path);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// NewCursor returns a pointer to the start of the memory in the arena.
|
/// NewCursor returns a pointer to the start of the memory in the arena.
|
||||||
///
|
///
|
||||||
|
|
|
@ -34,9 +34,12 @@ set(SOURCE_FILES
|
||||||
Dictionary.cc
|
Dictionary.cc
|
||||||
Exceptions.cpp
|
Exceptions.cpp
|
||||||
Test.cc
|
Test.cc
|
||||||
TLV.cc)
|
TLV.cc
|
||||||
|
Commander.cpp
|
||||||
|
Commander.h)
|
||||||
|
|
||||||
add_library(klib STATIC ${SOURCE_FILES} ${HEADER_FILES})
|
add_library(klib STATIC ${SOURCE_FILES} ${HEADER_FILES})
|
||||||
|
|
||||||
add_executable(phonebook phonebook.cpp)
|
add_executable(phonebook phonebook.cpp)
|
||||||
target_link_libraries(phonebook klib)
|
target_link_libraries(phonebook klib)
|
||||||
|
|
||||||
|
@ -67,8 +70,9 @@ add_custom_target(cloc
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||||
|
|
||||||
configure_file(klib.pc.in klib.pc @ONLY)
|
configure_file(klib.pc.in klib.pc @ONLY)
|
||||||
install(TARGETS klib LIBRARY DESTINATION ${PREFIX}/lib)
|
install(TARGETS klib LIBRARY DESTINATION lib)
|
||||||
install(FILES ${HEADER_FILES} DESTINATION include/{klib})
|
install(TARGETS phonebook RUNTIME DESTINATION bin)
|
||||||
|
install(FILES ${HEADER_FILES} DESTINATION include/klib)
|
||||||
install(FILES klibConfig.cmake DESTINATION share/klib/cmake)
|
install(FILES klibConfig.cmake DESTINATION share/klib/cmake)
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/klib.pc DESTINATION lib/pkgconfig)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/klib.pc DESTINATION lib/pkgconfig)
|
||||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION share/doc/klib)
|
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION share/doc/klib)
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
///
|
||||||
|
/// \file Commander.cpp
|
||||||
|
/// \author kyle
|
||||||
|
/// \created 10/10/23
|
||||||
|
/// \brief
|
||||||
|
/// \section COPYRIGHT
|
||||||
|
/// \section COPYRIGHT
|
||||||
|
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
||||||
|
///
|
||||||
|
/// Permission to use, copy, modify, and/or distribute this software for
|
||||||
|
/// any purpose with or without fee is hereby granted, provided that the
|
||||||
|
/// above copyright notice and this permission notice appear in all copies.
|
||||||
|
///
|
||||||
|
/// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||||
|
/// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||||
|
/// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||||
|
/// BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||||
|
/// OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||||
|
/// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
|
/// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||||
|
/// SOFTWARE.
|
||||||
|
///
|
||||||
|
/// @\section DESCRIPTION
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "Commander.h"
|
||||||
|
|
||||||
|
namespace klib {
|
||||||
|
|
||||||
|
|
||||||
|
Subcommand::Status
|
||||||
|
Subcommand::Run(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < this->args) {
|
||||||
|
std::cerr << "[!] " << this->command << " expects ";
|
||||||
|
std::cerr << this->args << " args, but was given ";
|
||||||
|
std::cerr << argc << " args.\n";
|
||||||
|
return Subcommand::Status::NotEnoughArgs;
|
||||||
|
}
|
||||||
|
if (this->fn(argc, argv)) {
|
||||||
|
return Subcommand::Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Subcommand::Status::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
Commander::Commander()
|
||||||
|
: cmap()
|
||||||
|
{
|
||||||
|
this->cmap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Commander::Register(Subcommand scmd)
|
||||||
|
{
|
||||||
|
if (this->cmap.count(scmd.Name()) > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *pScmd = new Subcommand(scmd);
|
||||||
|
this->cmap[scmd.Name()] = pScmd;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Subcommand::Status
|
||||||
|
Commander::Run(std::string command, int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (this->cmap.count(command) != 1) {
|
||||||
|
return Subcommand::Status::CommandNotRegistered;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto scmd = this->cmap[command];
|
||||||
|
return scmd->Run(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // klib
|
|
@ -0,0 +1,59 @@
|
||||||
|
///
|
||||||
|
/// \file Commander.h
|
||||||
|
/// \author kyle
|
||||||
|
/// \created 2023-10-10
|
||||||
|
/// \brief Subprogram tooling.
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef KLIB_COMMANDER_H
|
||||||
|
#define KLIB_COMMANDER_H
|
||||||
|
|
||||||
|
namespace klib {
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::function<bool(int, char **)> CommanderFunc;
|
||||||
|
|
||||||
|
|
||||||
|
class Subcommand {
|
||||||
|
public:
|
||||||
|
enum class Status : uint8_t {
|
||||||
|
OK = 0,
|
||||||
|
NotEnoughArgs = 1,
|
||||||
|
Failed = 2,
|
||||||
|
CommandNotRegistered = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
Subcommand(std::string name, int argc, CommanderFunc func)
|
||||||
|
: fn(func), args(argc), command(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string Name() { return this->command; }
|
||||||
|
Status Run(int argc, char **argv);
|
||||||
|
private:
|
||||||
|
CommanderFunc fn;
|
||||||
|
int args;
|
||||||
|
std::string command;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Commander does this.
|
||||||
|
///
|
||||||
|
/// Longer description...
|
||||||
|
class Commander {
|
||||||
|
public:
|
||||||
|
Commander();
|
||||||
|
|
||||||
|
bool Register(Subcommand scmd);
|
||||||
|
Subcommand::Status Run(std::string command, int argc, char **argv);
|
||||||
|
private:
|
||||||
|
std::map<std::string, Subcommand *> cmap;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // klib
|
||||||
|
|
||||||
|
|
||||||
|
#endif //KLIB_COMMANDER_H
|
|
@ -64,7 +64,7 @@ Dictionary::Set(const char *key, uint8_t klen, const char *val, uint8_t vlen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// seek searches the Dictionary for the key.
|
||||||
uint8_t *
|
uint8_t *
|
||||||
Dictionary::seek(const char *key, uint8_t klen)
|
Dictionary::seek(const char *key, uint8_t klen)
|
||||||
{
|
{
|
||||||
|
@ -94,6 +94,21 @@ Dictionary::Contains(const char *key, uint8_t klen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Dictionary::Delete(const char *key, uint8_t klen)
|
||||||
|
{
|
||||||
|
auto *cursor = this->seek(key, klen);
|
||||||
|
|
||||||
|
if (cursor == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TLV::DeleteRecord(this->arena, cursor);
|
||||||
|
TLV::DeleteRecord(this->arena, cursor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Dictionary::spaceAvailable(uint8_t klen, uint8_t vlen)
|
Dictionary::spaceAvailable(uint8_t klen, uint8_t vlen)
|
||||||
{
|
{
|
||||||
|
@ -123,7 +138,6 @@ operator<<(std::ostream &os, const Dictionary &dictionary)
|
||||||
TLV::Record rec;
|
TLV::Record rec;
|
||||||
|
|
||||||
TLV::ReadFromMemory(rec, cursor);
|
TLV::ReadFromMemory(rec, cursor);
|
||||||
os << "Dictionary KV pairs" << std::endl;
|
|
||||||
if (rec.Tag == TLV::TAG_EMPTY) {
|
if (rec.Tag == TLV::TAG_EMPTY) {
|
||||||
os << "\t(NONE)" << std::endl;
|
os << "\t(NONE)" << std::endl;
|
||||||
return os;
|
return os;
|
||||||
|
|
|
@ -91,6 +91,13 @@ public:
|
||||||
/// \return True if the key is in the Dictionary, otherwise false.
|
/// \return True if the key is in the Dictionary, otherwise false.
|
||||||
bool Contains(const char *key, uint8_t klen);
|
bool Contains(const char *key, uint8_t klen);
|
||||||
|
|
||||||
|
/// Delete removes the key from the Dictionary.
|
||||||
|
///
|
||||||
|
/// \param key The key to look up.
|
||||||
|
/// \param klen The length of the key.
|
||||||
|
/// \return True if the key was removed, otherwise false.
|
||||||
|
bool Delete(const char *key, uint8_t klen);
|
||||||
|
|
||||||
|
|
||||||
/// DumpToFile is a wrapper aorund a call to Arena::Write on the
|
/// DumpToFile is a wrapper aorund a call to Arena::Write on the
|
||||||
/// underlying Arena.
|
/// underlying Arena.
|
||||||
|
@ -99,7 +106,7 @@ public:
|
||||||
/// \return 0 on success, -1 on failure.
|
/// \return 0 on success, -1 on failure.
|
||||||
int DumpToFile(const char *path);
|
int DumpToFile(const char *path);
|
||||||
|
|
||||||
/// operator<< writes the key pairs to the output stream.
|
/// operator<< writes the key pairs phonto the output stream.
|
||||||
///
|
///
|
||||||
/// \param os The output stream to write to.
|
/// \param os The output stream to write to.
|
||||||
/// \param dictionary The dictionary to write out.
|
/// \param dictionary The dictionary to write out.
|
||||||
|
|
|
@ -45,7 +45,7 @@ main(int argc, const char *argv[])
|
||||||
std::cout << "TESTPROG: " << argv[0] << std::endl;
|
std::cout << "TESTPROG: " << argv[0] << std::endl;
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
if (arena.Create(ARENA_FILE, ARENA_SIZE, 0644) == -1) {
|
if (arena.Create(ARENA_FILE, ARENA_SIZE) == -1) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
130
phonebook.cpp
130
phonebook.cpp
|
@ -7,10 +7,96 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#include "Arena.h"
|
#include "Arena.h"
|
||||||
|
#include "Commander.h"
|
||||||
#include "Dictionary.h"
|
#include "Dictionary.h"
|
||||||
using namespace klib;
|
using namespace klib;
|
||||||
|
|
||||||
static const char *defaultPhonebook = "pb.dat";
|
static const char *defaultPhonebook = "pb.dat";
|
||||||
|
static char *pbFile = (char *)defaultPhonebook;
|
||||||
|
static Arena arena;
|
||||||
|
static Dictionary pb(arena);
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
listFiles(int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void)argc; (void)argv;
|
||||||
|
cout << "[+] keys in '" << pbFile << "':\n";
|
||||||
|
cout << pb;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
newPhonebook(int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
|
||||||
|
auto size = std::stoul(string(argv[0]));
|
||||||
|
cout << "[+] create new " << size << "B phonebook '" << pbFile << "'\n";
|
||||||
|
|
||||||
|
return arena.Create(pbFile, size) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
delKey(int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
string key = argv[0];
|
||||||
|
|
||||||
|
cout << "[+] deleting key '" << key << "'\n";
|
||||||
|
return pb.Delete(key.c_str(), key.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
hasKey(int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
string key = argv[0];
|
||||||
|
|
||||||
|
cout << "[+] looking up '" << key << "': ";
|
||||||
|
if (pb.Contains(key.c_str(), key.size())) {
|
||||||
|
cout << "found\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "not found\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
getKey(int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
TLV::Record rec;
|
||||||
|
auto key = string(argv[0]);
|
||||||
|
|
||||||
|
cout << "[+] key '" << key << "' ";
|
||||||
|
if (!pb.Lookup(key.c_str(), key.size(), rec)) {
|
||||||
|
cout << "not found\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "-> " << rec.Val << "\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
putKey(int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
auto key = string(argv[0]);
|
||||||
|
auto val = string(argv[1]);
|
||||||
|
|
||||||
|
cout << "[+] setting '" << key << "' -> '" << val << "': ";
|
||||||
|
if (pb.Set(key.c_str(), key.size(), val.c_str(), val.size()) != 0) {
|
||||||
|
cout << "failed\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "set\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(ostream &os, int exc)
|
usage(ostream &os, int exc)
|
||||||
|
@ -19,9 +105,10 @@ usage(ostream &os, int exc)
|
||||||
os << "\nThe default filename is pb.dat.\n\n";
|
os << "\nThe default filename is pb.dat.\n\n";
|
||||||
os << "Usage:\n";
|
os << "Usage:\n";
|
||||||
os << "\tphonebook [-f file] list\n";
|
os << "\tphonebook [-f file] list\n";
|
||||||
|
os << "\tphonebook [-f file] new size\n";
|
||||||
os << "\tphonebook [-f file] del key\n";
|
os << "\tphonebook [-f file] del key\n";
|
||||||
os << "\tphonebook [-f file] has key\n";
|
os << "\tphonebook [-f file] has key\n";
|
||||||
os << "\tphonebook [-f file] get key value\n";
|
os << "\tphonebook [-f file] get key\n";
|
||||||
os << "\tphonebook [-f file] put key value\n";
|
os << "\tphonebook [-f file] put key value\n";
|
||||||
os << "\n";
|
os << "\n";
|
||||||
|
|
||||||
|
@ -31,12 +118,9 @@ usage(ostream &os, int exc)
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
Arena arena;
|
|
||||||
Dictionary pb(arena);
|
|
||||||
char *pbFile = (char *)defaultPhonebook;
|
|
||||||
int optind = 1;
|
int optind = 1;
|
||||||
|
|
||||||
for (optind; optind < argc; optind++) {
|
for (optind = 1; optind < argc; optind++) {
|
||||||
auto arg = string(argv[optind]);
|
auto arg = string(argv[optind]);
|
||||||
if (arg[0] != '-') break;
|
if (arg[0] != '-') break;
|
||||||
if (arg == "-h") usage(cout, 0);
|
if (arg == "-h") usage(cout, 0);
|
||||||
|
@ -53,18 +137,40 @@ main(int argc, char *argv[])
|
||||||
usage(cout, 0);
|
usage(cout, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto command = string(argv[optind++]);
|
||||||
|
Commander commander;
|
||||||
|
|
||||||
|
commander.Register(Subcommand("list", 0, listFiles));
|
||||||
|
commander.Register(Subcommand("new", 1, newPhonebook));
|
||||||
|
commander.Register(Subcommand("del", 1, delKey));
|
||||||
|
commander.Register(Subcommand("has", 1, hasKey));
|
||||||
|
commander.Register(Subcommand("get", 1, getKey));
|
||||||
|
commander.Register(Subcommand("put", 2, putKey));
|
||||||
|
|
||||||
|
if (command != "new") {
|
||||||
cout << "[+] loading phonebook from " << pbFile << "\n";
|
cout << "[+] loading phonebook from " << pbFile << "\n";
|
||||||
if (arena.Open(pbFile) != 0) {
|
if (arena.Open(pbFile) != 0) {
|
||||||
cerr << "Failed to open " << pbFile << "\n";
|
cerr << "Failed to open " << pbFile << "\n";
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto command = string(argv[optind++]);
|
|
||||||
|
|
||||||
if (command == "list") {
|
|
||||||
cout << pb << "\n";
|
|
||||||
} else if (command == "del") {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto result = commander.Run(command, argc-optind, argv+optind);
|
||||||
|
switch (result) {
|
||||||
|
case Subcommand::Status::OK:
|
||||||
|
std::cout << "[+] OK\n";
|
||||||
|
break;
|
||||||
|
case Subcommand::Status::NotEnoughArgs:
|
||||||
|
usage(cerr, 1);
|
||||||
|
break;
|
||||||
|
case Subcommand::Status::Failed:
|
||||||
|
cerr << "[!] '"<< command << "' failed\n";
|
||||||
|
break;
|
||||||
|
case Subcommand::Status::CommandNotRegistered:
|
||||||
|
cerr << "[!] '" << command << "' not registered.\n";
|
||||||
|
usage(cerr, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -99,7 +99,7 @@ main(int argc, const char *argv[])
|
||||||
|
|
||||||
Arena arenaFile;
|
Arena arenaFile;
|
||||||
|
|
||||||
if (-1 == arenaFile.Create(ARENA_FILE, ARENA_SIZE, 0644)) {
|
if (-1 == arenaFile.Create(ARENA_FILE, ARENA_SIZE)) {
|
||||||
abort();
|
abort();
|
||||||
} else if (!runSuite(arenaFile, "arenaFile")) {
|
} else if (!runSuite(arenaFile, "arenaFile")) {
|
||||||
abort();
|
abort();
|
||||||
|
|
Loading…
Reference in New Issue