added many flags; added driver code for engine

This commit is contained in:
Bob Polis 2020-11-20 17:54:16 +01:00
parent 26a2554ff0
commit ba714c52ca

View File

@ -10,11 +10,21 @@
#include <cstdlib>
#include <string>
#include <stdexcept>
#include <vector>
#include <memory>
#include <getopt.h>
#include <sqlite3.h>
#include "robinsonizer_mode.hpp"
#include "engine.hpp"
void print_help() {
std::cout << "usage: autogram [-h|--version]\n";
std::cout << " -a, --autogram <relaxed|strict|pangram> autogram type, default relaxed\n";
std::cout << " -h, --help show this help text and exit\n";
std::cout << " -i, --maxiiter <number> maximum iterations before restart, default 10\n";
std::cout << " -l, --lang <nl|en> language, default en\n";
std::cout << " -s, --start <text> start of sentence\n";
std::cout << " -v, --verbose increase verbosity\n";
std::cout << " --version show version number and exit\n";
}
@ -22,15 +32,51 @@ void print_version() {
std::cout << "autogram version 1.0\n";
}
void read_nums_from_db(std::vector<std::string>& numerals, const std::string& db_path, int lang_id) {
sqlite3* db {nullptr};
int rc = sqlite3_open(db_path.c_str(), &db);
if (rc) {
sqlite3_close(db);
throw std::runtime_error("can't open database");
}
std::unique_ptr<sqlite3, int(*)(sqlite3*)> dbh {db, sqlite3_close};
const char* query = "SELECT num FROM numerals WHERE language_id = ? ORDER BY value";
sqlite3_stmt* stmt {nullptr};
sqlite3_prepare_v2(db, query, -1, &stmt, nullptr);
std::unique_ptr<sqlite3_stmt, int(*)(sqlite3_stmt*)> stmth {stmt, sqlite3_finalize};
sqlite3_bind_int(stmt, 1, lang_id);
while (true) {
rc = sqlite3_step(stmt);
if (rc == SQLITE_ROW) {
const unsigned char* data = sqlite3_column_text(stmt, 0);
std::string num {reinterpret_cast<const char*>(data)};
numerals.push_back(num);
} else {
break;
}
}
}
int main(int argc, const char * argv[]) {
try {
robinsonizer_mode mode {robinsonizer_mode::lax_autogram};
std::string lang {"en"};
std::string start;
int maxiter {0};
std::string db_path {"numerals.db"};
unsigned int verbose {0};
int opt_char, opt_val;
struct option long_options[] = {
{"autogram", required_argument, nullptr, 'a'},
{"help", no_argument, nullptr, 'h'},
{"max-iter", required_argument, nullptr, 'i'},
{"lang", required_argument, nullptr, 'l'},
{"start", required_argument, nullptr, 's'},
{"verbose", required_argument, nullptr, 'v'},
{"version", no_argument, &opt_val, 1},
{nullptr, 0, nullptr, 0}
};
while ((opt_char = getopt_long(argc, const_cast<char* const *>(argv), "h", long_options, nullptr)) != -1) {
while ((opt_char = getopt_long(argc, const_cast<char* const *>(argv), "a:hi:l:s:v", long_options, nullptr)) != -1) {
std::string arg {optarg ? optarg : ""};
switch (opt_char) {
case 0: {
@ -42,9 +88,32 @@ int main(int argc, const char * argv[]) {
}
break;
}
case 'a':
if (arg == "relaxed") {
mode = robinsonizer_mode::lax_autogram;
} else if (arg == "strict") {
mode = robinsonizer_mode::strict_autogram;
} else if (arg == "pangram") {
mode = robinsonizer_mode::pangram;
} else {
throw std::invalid_argument("invalid autogram type");
}
break;
case 'h':
print_help();
return EXIT_SUCCESS;
case 'i':
maxiter = atoi(optarg);
break;
case 'l':
lang = arg;
break;
case 's':
start = arg;
break;
case 'v':
verbose++;
break;
case '?':
throw std::runtime_error("unrecognized option");
}
@ -55,11 +124,22 @@ int main(int argc, const char * argv[]) {
for (int i = optind; i < argc; ++i) {
try {
// process file argv[i]
db_path = argv[i];
break; // ignore other args
} catch (const std::runtime_error& ex) {
std::cerr << "autogram: " << ex.what() << '\n';
}
}
std::cout << "hello, autogram\n";
std::vector<std::string> numerals;
numerals.push_back(lang == "nl" ? "en" : "and");
read_nums_from_db(numerals, db_path, (lang == "nl" ? 1 : 2));
if (start.size() == 0) start = "This sentence contains";
if (maxiter == 0) maxiter = 10;
engine robinsonizer {start, std::move(numerals), maxiter, mode, verbose};
robinsonizer.run();
std::cout << robinsonizer << '\n';
} catch (const std::exception& ex) {
std::cerr << "autogram: " << ex.what() << '\n';
return EXIT_FAILURE;