aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/CMakeLists.txt74
-rw-r--r--apps/SoilMoisture.cpp3
-rw-r--r--apps/apps.cpp75
-rw-r--r--apps/apps.h34
-rw-r--r--apps/ble-inspect-device.cpp (renamed from apps/ble-inspect-device.h)9
-rw-r--r--apps/ble-scan.cpp (renamed from apps/ble-scan.h)10
-rw-r--r--apps/generate.cpp76
-rw-r--r--apps/launcher.cpp104
-rw-r--r--apps/sample-add-timestamp.cpp (renamed from apps/sample-add-timestamp.h)10
-rw-r--r--apps/sample-convert.cpp (renamed from apps/sample-convert.h)10
-rw-r--r--apps/sample-select.cpp (renamed from apps/sample-select.h)9
-rw-r--r--apps/sm-db-insert.cpp (renamed from apps/sm-db-insert.h)11
-rw-r--r--apps/sm-db-select.cpp (renamed from apps/sm-db-select.h)10
-rw-r--r--apps/sm-get-value.cpp (renamed from apps/sm-get-value.h)9
-rw-r--r--apps/sm-serial-read-all.cpp (renamed from apps/sm-serial-read-all.h)12
-rw-r--r--apps/sm-serial-read.cpp (renamed from apps/sm-serial-read.h)12
16 files changed, 205 insertions, 263 deletions
diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt
index 8ba5a0a..b8255d1 100644
--- a/apps/CMakeLists.txt
+++ b/apps/CMakeLists.txt
@@ -9,6 +9,16 @@ list(APPEND APPS sm-get-value)
list(APPEND APPS sm-serial-read)
list(APPEND APPS sm-serial-read-all)
+add_library(apps OBJECT
+ apps.cpp apps.h
+ SoilMoisture.cpp SoilMoisture.h)
+target_include_directories(apps
+ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
+ PUBLIC "${PROJECT_SOURCE_DIR}/include"
+ PUBLIC "${PROJECT_SOURCE_DIR}/json/src"
+ PUBLIC "${PROJECT_SOURCE_DIR}/sensor/include"
+ PUBLIC "${LOG4CPLUS_INCLUDE_DIRECTORIES}")
+
# Boost
find_package(Boost COMPONENTS regex system program_options REQUIRED)
@@ -30,50 +40,24 @@ if(LOG4CPLUS_LIBRARIES MATCHES NOTFOUND)
message(FATAL_ERROR "Could not find log4cplus library files")
endif()
-add_executable(generate generate.cpp)
-
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated)
-
-add_custom_command(
- OUTPUT generated/apps-list.gen.h
- COMMAND generate ${CMAKE_CURRENT_BINARY_DIR}/generated/apps-list.gen.h ${APPS}
- DEPENDS generate ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
-
-foreach(app ${APPS})
- list(APPEND APPS_SOURCES ${app}.h)
-endforeach()
-
-list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/generated/apps-list.gen.h)
-list(APPEND SOURCES SoilMoisture.cpp SoilMoisture.h)
-list(APPEND SOURCES apps.cpp apps.h)
-
-add_executable(launcher launcher.cpp
- ${SOURCES}
- ${APPS_SOURCES})
-target_include_directories(launcher
- PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/generated
- PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
- PUBLIC "${PROJECT_SOURCE_DIR}/include"
- PUBLIC "${PROJECT_SOURCE_DIR}/json/src"
- PUBLIC "${PROJECT_SOURCE_DIR}/sensor/include"
- PUBLIC "${LOG4CPLUS_INCLUDE_DIRECTORIES}")
-
-target_link_libraries(launcher ble)
-target_link_libraries(launcher trygvis-sensor)
-target_link_libraries(launcher ${Boost_LIBRARIES})
-target_link_libraries(launcher ${BLUEZ_LIBRARIES})
-target_link_libraries(launcher ${PQXX_LIBRARIES})
-target_link_libraries(launcher ${LOG4CPLUS_LIBRARIES})
-target_link_libraries(launcher ${CMAKE_THREAD_LIBS_INIT})
-
foreach(app ${APPS})
- add_custom_command(
- TARGET launcher POST_BUILD
- COMMAND ln -sf ../libexec/launcher ${app})
-
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${app} DESTINATION bin)
+ add_executable(${app} ${app}.cpp $<TARGET_OBJECTS:apps>)
+
+ target_include_directories(${app}
+ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
+ PUBLIC "${PROJECT_SOURCE_DIR}/include"
+ PUBLIC "${PROJECT_SOURCE_DIR}/json/src"
+ PUBLIC "${PROJECT_SOURCE_DIR}/sensor/include"
+ PUBLIC "${LOG4CPLUS_INCLUDE_DIRECTORIES}")
+
+ target_link_libraries(${app}
+ ble
+ trygvis-sensor
+ ${Boost_LIBRARIES}
+ ${BLUEZ_LIBRARIES}
+ ${PQXX_LIBRARIES}
+ ${LOG4CPLUS_LIBRARIES}
+ ${CMAKE_THREAD_LIBS_INIT})
+
+ install(TARGETS ${app} RUNTIME DESTINATION bin)
endforeach()
-
-set_target_properties(launcher PROPERTIES INSTALL_RPATH "\\$ORIGIN/../lib/trygvis")
-install(TARGETS launcher
- RUNTIME DESTINATION libexec)
diff --git a/apps/SoilMoisture.cpp b/apps/SoilMoisture.cpp
index 044ba21..1d6888c 100644
--- a/apps/SoilMoisture.cpp
+++ b/apps/SoilMoisture.cpp
@@ -69,8 +69,7 @@ SoilMoisture SoilMoisture::create(shared_ptr<BluetoothGatt> gatt) {
}
SoilMoisture::SoilMoisture(shared_ptr<BluetoothGatt> gatt, BluetoothGattService &s, BluetoothGattCharacteristic &c)
- : gatt(std::move(gatt)), s(s), c(c) {
-}
+ : gatt(std::move(gatt)), s(s), c(c) {}
ByteBuffer SoilMoisture::writeAndRead(ByteBuffer &requestBytes) {
requestBytes.setCursor(0);
diff --git a/apps/apps.cpp b/apps/apps.cpp
index b353e85..916b0e0 100644
--- a/apps/apps.cpp
+++ b/apps/apps.cpp
@@ -1,5 +1,7 @@
#include "apps.h"
#include <netdb.h>
+#include <log4cplus/consoleappender.h>
+#include <log4cplus/configurator.h>
namespace trygvis {
namespace apps {
@@ -43,5 +45,78 @@ std::string get_hostname() {
void app_execution::usage() {
cerr << desc << endl;
}
+
+const po::options_description logging_options() {
+ po::options_description desc;
+
+ return desc;
+}
+
+void setup_logging(string app_name) {
+ Appender *console = new ConsoleAppender(true, true);
+
+ string pattern = string("%-5p ") /*"%6r "*/ + app_name + "/%-20c %m%n"; // add %M (function name)
+
+ PatternLayout *layout = new PatternLayout(LOG4CPLUS_TEXT(pattern));
+ console->setLayout(auto_ptr<Layout>(layout));
+
+ Hierarchy &h = Logger::getDefaultHierarchy();
+ h.getRoot().addAppender(SharedAppenderPtr(console));
+}
+
+int launch_app(app *app, int argc, const char *argv[]) {
+ po::options_description all("Options");
+
+ auto all_options = all.add_options();
+ all_options("help", "This help message");
+ app->add_options(all_options);
+
+ all.add(logging_options());
+ app->add_extra_options(all);
+
+ po::variables_map vm;
+
+ try {
+ auto parsed = po::parse_command_line(argc, argv, all);
+ po::store(parsed, vm);
+
+ po::notify(vm);
+
+ auto unrecognized = po::collect_unrecognized(parsed.options, po::include_positional);
+
+ if (vm.count("help")) {
+ cerr << all << "\n";
+ return EXIT_FAILURE;
+ }
+
+ if (unrecognized.size()) {
+ cerr << "Unrecognized option: " << unrecognized.at(0) << "\n";
+ return EXIT_FAILURE;
+ }
+
+ setup_logging(app->app_name);
+
+ Logger logger = Logger::getInstance(LOG4CPLUS_TEXT("main"));
+
+ app_execution execution(all, vm, logger);
+
+ return app->main(execution);
+ } catch (po::required_option &e) {
+ cerr << "Missing required option: " << e.get_option_name() << endl;
+ cerr << all << endl;
+ return EXIT_FAILURE;
+ } catch (po::unknown_option &e) {
+ cerr << e.what() << endl;
+ return EXIT_FAILURE;
+ }
+}
+
+int real_main(app *app, int argc, const char *argv[]) {
+ if (argc == 0) {
+ return EXIT_FAILURE;
+ }
+
+ return launch_app(app, argc, argv);
+}
}
}
diff --git a/apps/apps.h b/apps/apps.h
index 4a69b05..e9338a4 100644
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -16,8 +16,7 @@ using json = nlohmann::json;
class missing_key : public std::runtime_error {
public:
- missing_key(const json::string_t key) : runtime_error("Missing key: " + key), key(key) {
- }
+ missing_key(const json::string_t key) : runtime_error("Missing key: " + key), key(key) {}
const json::string_t key;
};
@@ -33,11 +32,17 @@ T get(json j, std::string key) {
return ref;
}
+class unknown_app : public std::runtime_error {
+public:
+ unknown_app(const std::string &app_name) : runtime_error("Unknown application: " + app_name), app_name(app_name) {}
+
+ const std::string app_name;
+};
+
class app_execution {
public:
app_execution(po::options_description desc, po::variables_map vm, Logger logger)
- : desc(desc), vm(vm), logger(logger) {
- }
+ : desc(desc), vm(vm), logger(logger) {}
const po::options_description desc;
const po::variables_map vm;
@@ -48,14 +53,19 @@ public:
class app {
public:
- app(std::string app_name) : app_name(app_name) {
- }
+ app(std::string app_name) : app_name(app_name) {}
+
+ app(const app &) = delete;
+
+ app(app &&) = default;
virtual ~app() = default;
- virtual void add_options(po::options_description_easy_init &options){};
+ app &operator=(const app &) = delete;
+
+ virtual void add_options(po::options_description_easy_init &options) {}
- virtual void add_extra_options(po::options_description &options){};
+ virtual void add_extra_options(po::options_description &options) {}
virtual int main(app_execution &execution) = 0;
@@ -64,14 +74,14 @@ public:
std::string get_hostname();
+int real_main(app *app, int argc, const char *argv[]);
+
template <typename T>
class noop_delete {
public:
- void operator()(T *) const {
- }
+ void operator()(T *) const {}
};
-static inline void noop_deleter(void *) {
-}
+static inline void noop_deleter(void *) {}
}
}
diff --git a/apps/ble-inspect-device.h b/apps/ble-inspect-device.cpp
index ff19ba1..763dd9a 100644
--- a/apps/ble-inspect-device.h
+++ b/apps/ble-inspect-device.cpp
@@ -14,8 +14,7 @@ using namespace trygvis::apps;
class ble_inspect_device : public app {
public:
- ble_inspect_device() : app("ble-inspect-device") {
- }
+ ble_inspect_device() : app("ble-inspect-device") {}
~ble_inspect_device() = default;
@@ -72,3 +71,9 @@ public:
};
}
}
+
+int main(int argc, const char *argv[]) {
+ using namespace trygvis::apps;
+
+ return real_main(new ble_inspect_device(), argc, argv);
+}
diff --git a/apps/ble-scan.h b/apps/ble-scan.cpp
index 2c183e3..839a9fa 100644
--- a/apps/ble-scan.h
+++ b/apps/ble-scan.cpp
@@ -2,6 +2,7 @@
#include "apps.h"
#include <csignal>
+#include "apps.h"
namespace trygvis {
namespace apps {
@@ -21,8 +22,7 @@ static void signal_handler(int signal) {
class ble_scan : public app {
public:
- ble_scan() : app("ble-scan") {
- }
+ ble_scan() : app("ble-scan") {}
~ble_scan() = default;
@@ -77,3 +77,9 @@ public:
};
}
}
+
+int main(int argc, const char *argv[]) {
+ using namespace trygvis::apps;
+
+ return real_main(new ble_scan(), argc, argv);
+}
diff --git a/apps/generate.cpp b/apps/generate.cpp
deleted file mode 100644
index a088e6e..0000000
--- a/apps/generate.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include <cstdlib>
-#include <iostream>
-#include <fstream>
-#include <regex>
-
-using namespace std;
-
-int main(int argc, char *argv[]) {
- cout << "Generating " << argv[1] << endl;
-
- ofstream out;
-
- out.open(argv[1], ofstream::out);
-
- if (!out.is_open()) {
- return EXIT_FAILURE;
- }
-
- out << "#pragma once" << endl
- << endl
- << "#include <string>" << endl
- << "#include <boost/algorithm/string/predicate.hpp>" << endl
- << endl;
-
- vector<pair<string, string>> apps;
-
- regex r("-");
- for (int i = 2; i < argc; i++) {
- string app_name = argv[i];
- stringstream buf;
-
- regex_replace(ostream_iterator<char>(buf), app_name.begin(), app_name.end(), r, "_");
- string class_name = buf.str();
-
- apps.emplace_back(make_pair(app_name, class_name));
- }
-
- for_each(begin(apps), end(apps), [&](pair<string, string> pair) {
- // out << "class " << pair.second << ";" << endl;
- out << "#include \"" << pair.first << ".h\"" << endl;
- });
- out << endl;
-
- bool first = true;
-
- out << "namespace trygvis {" << endl
- << "namespace apps {" << endl
- << endl
- << "template<typename App>" << endl
- << "int launch_app(int argc, const char *argv[]);" << endl
- << endl;
-
- out << "int launch(const std::string app_name, int argc, const char *argv[]) {" << endl;
-
- for_each(begin(apps), end(apps), [&](auto pair) {
- out << " ";
- if (!first) {
- out << "} else ";
- } else {
- first = false;
- }
-
- out << "if (boost::ends_with(app_name, \"" << pair.first << "\")) {" << endl
- << " return launch_app<" << pair.second << ">(argc, argv);" << endl;
- });
-
- out << " } else {" << endl
- << " return EXIT_FAILURE;" << endl
- << " }" << endl
- << "}" << endl
- << endl
- << "}" << endl
- << "}" << endl;
-
- return EXIT_SUCCESS;
-}
diff --git a/apps/launcher.cpp b/apps/launcher.cpp
deleted file mode 100644
index 0b97a59..0000000
--- a/apps/launcher.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "apps.h"
-#include "apps-list.gen.h"
-#include <log4cplus/consoleappender.h>
-#include <log4cplus/configurator.h>
-
-namespace trygvis {
-namespace apps {
-
-using namespace std;
-
-const po::options_description logging_options() {
- po::options_description desc;
-
- return desc;
-}
-
-void setup_logging(string app_name) {
- Appender *console = new ConsoleAppender(true, true);
-
- string pattern = string("%-5p ") /*"%6r "*/ + app_name + "/%-20c %m%n"; // add %M (function name)
-
- PatternLayout *layout = new PatternLayout(LOG4CPLUS_TEXT(pattern));
- console->setLayout(auto_ptr<Layout>(layout));
-
- Hierarchy &h = Logger::getDefaultHierarchy();
- h.getRoot().addAppender(SharedAppenderPtr(console));
-}
-
-template <typename App>
-int launch_app(int argc, const char *argv[]) {
- App app;
-
- po::options_description all("Options");
-
- auto all_options = all.add_options();
- all_options("help", "This help message");
- app.add_options(all_options);
-
- all.add(logging_options());
- app.add_extra_options(all);
-
- po::variables_map vm;
-
- try {
- auto parsed = po::parse_command_line(argc, argv, all);
- po::store(parsed, vm);
-
- po::notify(vm);
-
- auto unrecognized = po::collect_unrecognized(parsed.options, po::include_positional);
-
- if (vm.count("help")) {
- cerr << all << "\n";
- return EXIT_FAILURE;
- }
-
- if (unrecognized.size()) {
- cerr << "Unrecognized option: " << unrecognized.at(0) << "\n";
- return EXIT_FAILURE;
- }
-
- setup_logging(app.app_name);
-
- Logger logger = Logger::getInstance(LOG4CPLUS_TEXT("main"));
-
- app_execution execution(all, vm, logger);
-
- return app.main(execution);
- } catch (po::required_option &e) {
- cerr << "Missing required option: " << e.get_option_name() << endl;
- cerr << all << endl;
- return EXIT_FAILURE;
- } catch (po::unknown_option &e) {
- cerr << e.what() << endl;
- return EXIT_FAILURE;
- }
-}
-}
-}
-
-using namespace std;
-using namespace trygvis::apps;
-
-int main(int argc, const char *argv[]) {
- if (argc == 0) {
- return EXIT_FAILURE;
- }
-
- string app_name;
- if (boost::ends_with(argv[0], "launcher")) {
- if (argc <= 1) {
- cerr << "Missing required argument: app" << endl;
- return EXIT_FAILURE;
- }
-
- app_name = argv[1];
- --argc;
- ++argv;
- } else {
- app_name = argv[0];
- }
-
- return launch(app_name, argc, argv);
-}
diff --git a/apps/sample-add-timestamp.h b/apps/sample-add-timestamp.cpp
index 8439519..8bc4bac 100644
--- a/apps/sample-add-timestamp.h
+++ b/apps/sample-add-timestamp.cpp
@@ -2,6 +2,7 @@
#include "trygvis/sensor/io.h"
#include "apps.h"
#include <vector>
+#include "apps.h"
namespace trygvis {
namespace apps {
@@ -47,8 +48,7 @@ private:
sample_format_type output_format;
public:
- sample_add_timestamp() : app("sample-add-timestamp") {
- }
+ sample_add_timestamp() : app("sample-add-timestamp") {}
~sample_add_timestamp() = default;
@@ -93,3 +93,9 @@ public:
};
}
}
+
+int main(int argc, const char *argv[]) {
+ using namespace trygvis::apps;
+
+ return real_main(new sample_add_timestamp(), argc, argv);
+}
diff --git a/apps/sample-convert.h b/apps/sample-convert.cpp
index 9a2f99a..f592291 100644
--- a/apps/sample-convert.h
+++ b/apps/sample-convert.cpp
@@ -4,6 +4,7 @@
#include "apps.h"
#include <fstream>
#include <boost/tokenizer.hpp>
+#include "apps.h"
namespace trygvis {
namespace apps {
@@ -26,8 +27,7 @@ private:
string table_name;
public:
- sample_convert() : app("sample-convert") {
- }
+ sample_convert() : app("sample-convert") {}
~sample_convert() = default;
@@ -116,3 +116,9 @@ public:
};
}
}
+
+int main(int argc, const char *argv[]) {
+ using namespace trygvis::apps;
+
+ return real_main(new sample_convert(), argc, argv);
+}
diff --git a/apps/sample-select.h b/apps/sample-select.cpp
index 8ae5cc3..d067af4 100644
--- a/apps/sample-select.h
+++ b/apps/sample-select.cpp
@@ -16,8 +16,7 @@ private:
string fields;
public:
- sample_select() : app("sample-select") {
- }
+ sample_select() : app("sample-select") {}
~sample_select() = default;
@@ -117,3 +116,9 @@ public:
};
}
}
+
+int main(int argc, const char *argv[]) {
+ using namespace trygvis::apps;
+
+ return real_main(new sample_select(), argc, argv);
+}
diff --git a/apps/sm-db-insert.h b/apps/sm-db-insert.cpp
index 7e08268..b93be09 100644
--- a/apps/sm-db-insert.h
+++ b/apps/sm-db-insert.cpp
@@ -3,6 +3,7 @@
#include <pqxx/connection.hxx>
#include <pqxx/transaction.hxx>
#include "json.hpp"
+#include "apps.h"
#include <fstream>
namespace trygvis {
@@ -15,8 +16,7 @@ using json = nlohmann::json;
class sm_db_insert : public app {
public:
- sm_db_insert() : app("sm-db-insert") {
- }
+ sm_db_insert() : app("sm-db-insert") {}
~sm_db_insert() = default;
@@ -80,3 +80,10 @@ public:
};
}
}
+
+
+int main(int argc, const char *argv[]) {
+ using namespace trygvis::apps;
+
+ return real_main(new sm_db_insert(), argc, argv);
+}
diff --git a/apps/sm-db-select.h b/apps/sm-db-select.cpp
index 78678c5..2390733 100644
--- a/apps/sm-db-select.h
+++ b/apps/sm-db-select.cpp
@@ -3,6 +3,7 @@
#include <pqxx/connection.hxx>
#include <pqxx/transaction.hxx>
#include "json.hpp"
+#include "apps.h"
namespace trygvis {
namespace apps {
@@ -14,8 +15,7 @@ using json = nlohmann::json;
class sm_db_select : public app {
public:
- sm_db_select() : app("sm-db-select") {
- }
+ sm_db_select() : app("sm-db-select") {}
~sm_db_select() = default;
@@ -76,3 +76,9 @@ public:
};
}
}
+
+int main(int argc, const char *argv[]) {
+ using namespace trygvis::apps;
+
+ return real_main(new sm_db_select(), argc, argv);
+}
diff --git a/apps/sm-get-value.h b/apps/sm-get-value.cpp
index 5893d23..19b0066 100644
--- a/apps/sm-get-value.h
+++ b/apps/sm-get-value.cpp
@@ -22,8 +22,7 @@ using namespace trygvis::sensor::io;
class sm_get_value : public app {
public:
- sm_get_value() : app("sm-get-value") {
- }
+ sm_get_value() : app("sm-get-value") {}
~sm_get_value() = default;
@@ -178,3 +177,9 @@ public:
};
}
}
+
+int main(int argc, const char *argv[]) {
+ using namespace trygvis::apps;
+
+ return real_main(new sm_get_value(), argc, argv);
+}
diff --git a/apps/sm-serial-read-all.h b/apps/sm-serial-read-all.cpp
index b87727b..bf5ef11 100644
--- a/apps/sm-serial-read-all.h
+++ b/apps/sm-serial-read-all.cpp
@@ -22,8 +22,7 @@ namespace sm_serial_read_all_utils {
class port_handler {
public:
port_handler(string &port_name, serial_port &port, unique_ptr<SampleStreamParser> parser)
- : port_name(port_name), port(port), parser(move(parser)) {
- }
+ : port_name(port_name), port(port), parser(move(parser)) {}
void run() {
auto packet = make_shared<vector<uint8_t>>(1024);
@@ -90,8 +89,7 @@ class sm_serial_read_all : public app {
typedef trygvis::apps::sm_serial_read_all_utils::port_handler port_handler;
public:
- sm_serial_read_all() : app("sm-serial-read-all") {
- }
+ sm_serial_read_all() : app("sm-serial-read-all") {}
~sm_serial_read_all() = default;
@@ -165,3 +163,9 @@ public:
};
}
}
+
+int main(int argc, const char *argv[]) {
+ using namespace trygvis::apps;
+
+ return real_main(new sm_serial_read_all(), argc, argv);
+}
diff --git a/apps/sm-serial-read.h b/apps/sm-serial-read.cpp
index dcfcc73..5005554 100644
--- a/apps/sm-serial-read.h
+++ b/apps/sm-serial-read.cpp
@@ -23,8 +23,7 @@ namespace sm_serial_read_utils {
class port_handler {
public:
port_handler(string port_name, serial_port &serial_port, shared_ptr<KeyValueSampleStreamParser> input)
- : port_name(port_name), port(serial_port), input(input) {
- }
+ : port_name(port_name), port(serial_port), input(input) {}
void run() {
auto packet = make_shared<vector<uint8_t>>(1024);
@@ -55,8 +54,7 @@ class sm_serial_read : public app {
typedef trygvis::apps::sm_serial_read_utils::port_handler port_handler;
public:
- sm_serial_read() : app("sm-serial-read") {
- }
+ sm_serial_read() : app("sm-serial-read") {}
~sm_serial_read() = default;
@@ -105,3 +103,9 @@ public:
};
}
}
+
+int main(int argc, const char *argv[]) {
+ using namespace trygvis::apps;
+
+ return real_main(new sm_serial_read(), argc, argv);
+}