add_executable(caffegen ${SOURCES})
target_include_directories(caffegen PRIVATE include)
target_link_libraries(caffegen nncc_foundation nncc_frontend_caffe_core)
+ target_link_libraries(caffegen cli)
endif(TARGET nncc_frontend_caffe_core)
+++ /dev/null
-#ifndef __COMMAND_H__
-#define __COMMAND_H__
-
-struct Command
-{
- virtual ~Command() = default;
-
- virtual int run(int argc, char **argv) const = 0;
-};
-
-#endif // __COMMAND_H__
#include <iostream>
-int DecodeCommand::run(int, char **) const
+int DecodeCommand::run(int, const char * const *) const
{
caffe::NetParameter param;
#ifndef __DECODE_COMMAND_H__
#define __DECODE_COMMAND_H__
-#include "Command.h"
+#include <cli/Command.h>
-struct DecodeCommand final : public Command
+struct DecodeCommand final : public cli::Command
{
- int run(int argc, char **argv) const override;
+ int run(int argc, const char * const *argv) const override;
};
#endif // __DECODE_COMMAND_H__
#include "EncodeCommand.h"
#include "DecodeCommand.h"
+#include <cli/App.h>
#include <nncc/foundation/Memory.h>
#include <map>
int main(int argc, char **argv)
{
- std::map<std::string, std::unique_ptr<Command>> commands;
+ cli::App app{argv[0]};
- commands["fill"] = nncc::foundation::make_unique<FillCommand>();
- commands["encode"] = nncc::foundation::make_unique<EncodeCommand>();
- commands["decode"] = nncc::foundation::make_unique<DecodeCommand>();
+ app.insert("fill", nncc::foundation::make_unique<FillCommand>());
+ app.insert("encode", nncc::foundation::make_unique<EncodeCommand>());
+ app.insert("decode", nncc::foundation::make_unique<DecodeCommand>());
- return commands.at(argv[1])->run(argc - 2, argv + 2);
+ return app.run(argc - 1, argv + 1);
}
#include <iostream>
-int EncodeCommand::run(int, char **) const
+int EncodeCommand::run(int, const char * const *) const
{
caffe::NetParameter param;
#ifndef __ENCODE_COMMAND_H__
#define __ENCODE_COMMAND_H__
-#include "Command.h"
+#include <cli/Command.h>
-struct EncodeCommand final : public Command
+struct EncodeCommand final : public cli::Command
{
- int run(int argc, char **argv) const override;
+ int run(int argc, const char * const *argv) const override;
};
#endif // __ENCODE_COMMAND_H__
#include <random>
#include <iostream>
-int FillCommand::run(int, char **) const
+int FillCommand::run(int, const char * const *) const
{
auto param = nncc::foundation::make_unique<::caffe::NetParameter>();
#ifndef __FILL_COMMAND_H__
#define __FILL_COMMAND_H__
-#include "Command.h"
+#include <cli/Command.h>
-struct FillCommand final : public Command
+struct FillCommand final : public cli::Command
{
- int run(int argc, char **argv) const override;
+ int run(int argc, const char * const *argv) const override;
};
#endif // __FILL_COMMAND_H__
add_executable(caffekit ${SOURCES})
target_link_libraries(caffekit nncc_foundation)
+target_link_libraries(caffekit cli)
target_link_libraries(caffekit caffe)
-struct Command
-{
- virtual ~Command() = default;
-
- virtual int run(int argc, char **argv) const = 0;
-};
-
+#include <cli/Command.h>
#include <caffe/caffe.hpp>
#include <iostream>
-class RunCommand final : public Command
+class RunCommand final : public cli::Command
{
public:
- int run(int argc, char **argv) const override;
+ int run(int argc, const char * const *argv) const override;
};
-int RunCommand::run(int argc, char **argv) const
+int RunCommand::run(int argc, const char * const *argv) const
{
// USAGE: HEADER run [.prototxt] ([.caffemodel])
caffe::Net<float> net(argv[0], caffe::TEST);
}
#include <nncc/foundation/Memory.h>
+#include <cli/App.h>
#include <map>
#include <memory>
int main(int argc, char **argv)
{
- std::map<std::string, std::unique_ptr<Command>> commands;
-
- commands["run"] = nncc::foundation::make_unique<RunCommand>();
+ cli::App app{argv[0]};
- if (argc < 2)
- {
- std::cerr << "ERROR: COMMAND is not provided" << std::endl;
- std::cerr << std::endl;
- std::cerr << "USAGE: " << argv[0] << " [COMMAND] ..." << std::endl;
- return 255;
- }
-
- // USAGE: HEADER [command] ...
- if (commands.find(argv[1]) == commands.end())
- {
- std::cerr << "ERROR: '" << argv[1] << "' is not a valid command" << std::endl;
- std::cerr << std::endl;
- std::cerr << "USAGE: " << argv[0] << " [COMMAND] ..." << std::endl;
- std::cerr << std::endl;
- std::cerr << "SUPPORTED COMMANDS:" << std::endl;
- for (auto it = commands.begin(); it != commands.end(); ++it)
- {
- std::cerr << " " << it->first << std::endl;
- }
- return 255;
- }
+ app.insert("run", nncc::foundation::make_unique<RunCommand>());
- return commands.at(argv[1])->run(argc - 2, argv + 2);
+ return app.run(argc - 1, argv + 1);
}
--- /dev/null
+list(APPEND SOURCES "src/App.cpp")
+list(APPEND TESTS "src/App.test.cpp")
+
+add_library(cli ${SOURCES})
+target_include_directories(cli PUBLIC include)
+
+nncc_find_package(GTest QUIET)
+
+if(NOT GTest_FOUND)
+ return()
+endif(NOT GTest_FOUND)
+
+add_executable(cli_test ${TESTS})
+target_link_libraries(cli_test cli)
+target_link_libraries(cli_test nncc_foundation)
+target_link_libraries(cli_test gtest_main)
+add_test(cli_test cli_test)
--- /dev/null
+#ifndef __CLI_APP_H__
+#define __CLI_APP_H__
+
+#include "Command.h"
+
+#include <map>
+#include <memory>
+#include <string>
+
+namespace cli
+{
+
+class App
+{
+public:
+ explicit App(const std::string &name);
+
+public:
+ App &insert(const std::string &tag, std::unique_ptr<Command> &&command);
+
+public:
+ int run(int argc, const char * const *argv) const;
+
+private:
+ const std::string _name;
+ std::map<std::string, std::unique_ptr<Command>> _commands;
+};
+
+} // namespace cli
+
+#endif // __APP_H__
--- /dev/null
+#ifndef __CLI_COMMAND_H__
+#define __CLI_COMMAND_H__
+
+namespace cli
+{
+
+struct Command
+{
+ virtual ~Command() = default;
+
+ virtual int run(int argc, const char * const *argv) const = 0;
+};
+
+} // namespace cli
+
+#endif // __CLI_COMMAND_H__
--- /dev/null
+#include "cli/App.h"
+
+#include <iostream>
+#include <cassert>
+
+namespace cli
+{
+
+App::App(const std::string &name) : _name{name}
+{
+ // DO NOTHING
+}
+
+App &App::insert(const std::string &tag, std::unique_ptr<Command> &&command)
+{
+ assert(_commands.find(tag) == _commands.end());
+
+ _commands[tag] = std::move(command);
+
+ return (*this);
+}
+
+int App::run(int argc, const char * const *argv) const
+{
+ if (argc < 1)
+ {
+ std::cerr << "ERROR: COMMAND is not provided" << std::endl;
+ std::cerr << std::endl;
+ std::cerr << "USAGE: " << _name << " [COMMAND] ..." << std::endl;
+ return 255;
+ }
+
+ const std::string command{argv[0]};
+
+ auto it = _commands.find(command);
+
+ if (it == _commands.end())
+ {
+ std::cerr << "ERROR: '" << command << "' is not a valid command" << std::endl;
+ std::cerr << std::endl;
+ std::cerr << "USAGE: " << _name << " [COMMAND] ..." << std::endl;
+ std::cerr << std::endl;
+ std::cerr << "SUPPORTED COMMANDS:" << std::endl;
+ for (auto it = _commands.begin(); it != _commands.end(); ++it)
+ {
+ std::cerr << " " << it->first << std::endl;
+ }
+ return 255;
+ }
+
+ return it->second->run(argc - 1, argv + 1);
+}
+
+} // namespace cli
--- /dev/null
+#include "cli/App.h"
+
+#include <nncc/foundation/Memory.h>
+
+#include <gtest/gtest.h>
+
+class RecordCommand final : public cli::Command
+{
+public:
+ RecordCommand(int ret, std::string &out) : _ret{ret}, _out(out)
+ {
+ // DO NOTHING
+ }
+
+public:
+ int run(int argc, const char * const *argv) const override
+ {
+ _out += std::to_string(argc);
+
+ for (int n = 0; n < argc; ++n)
+ {
+ _out += ";";
+ _out += argv[n];
+ }
+
+ return _ret;
+ }
+
+private:
+ int const _ret;
+ std::string &_out;
+};
+
+TEST(APP, run)
+{
+ cli::App app("test");
+
+ std::string args;
+ app.insert("record", nncc::foundation::make_unique<RecordCommand>(3, args));
+
+ const char *argv[] = {
+ "record",
+ "hello",
+ "world"
+ };
+
+ int ret = app.run(3, argv);
+
+ ASSERT_EQ(ret, 3);
+ ASSERT_EQ(args, "2;hello;world");
+}
add_executable(tflitekit ${SOURCES})
target_link_libraries(tflitekit nncc_foundation)
+target_link_libraries(tflitekit cli)
target_link_libraries(tflitekit tensorflowlite)
-struct Command
-{
- virtual ~Command() = default;
-
- virtual int run(int argc, char **argv) const = 0;
-};
-
#include "tensorflow/contrib/lite/kernels/register.h"
#include "tensorflow/contrib/lite/model.h"
+#include <cli/Command.h>
#include <iostream>
using namespace tflite;
using namespace tflite::ops::builtin;
-class RunCommand final : public Command
+class RunCommand final : public cli::Command
{
public:
- int run(int argc, char **argv) const override;
+ int run(int argc, const char * const *argv) const override;
};
-int RunCommand::run(int argc, char **argv) const
+int RunCommand::run(int argc, const char * const *argv) const
{
// USAGE: HEADER run [.tflite]
const auto filename = argv[0];
}
#include <nncc/foundation/Memory.h>
+#include <cli/App.h>
#include <map>
#include <memory>
int main(int argc, char **argv)
{
- std::map<std::string, std::unique_ptr<Command>> commands;
-
- commands["run"] = nncc::foundation::make_unique<RunCommand>();
-
- if (argc < 2)
- {
- std::cerr << "ERROR: COMMAND is not provided" << std::endl;
- std::cerr << std::endl;
- std::cerr << "USAGE: " << argv[0] << " [COMMAND] ..." << std::endl;
- return 255;
- }
-
- // USAGE: HEADER [command] ...
- if (commands.find(argv[1]) == commands.end())
- {
- std::cerr << "ERROR: '" << argv[1] << "' is not a valid command" << std::endl;
- std::cerr << std::endl;
- std::cerr << "USAGE: " << argv[0] << " [COMMAND] ..." << std::endl;
- std::cerr << std::endl;
- std::cerr << "SUPPORTED COMMANDS:" << std::endl;
- for (auto it = commands.begin(); it != commands.end(); ++it)
- {
- std::cerr << " " << it->first << std::endl;
- }
- return 255;
- }
-
- return commands.at(argv[1])->run(argc - 2, argv + 2);
+ cli::App app{argv[0]};
+
+ app.insert("run", nncc::foundation::make_unique<RunCommand>());
+
+ return app.run(argc - 1, argv + 1);
}