Skip to content

Commit

Permalink
Rework command line option parsing to store values directly in class …
Browse files Browse the repository at this point in the history
…member variables

The program options libary has a convenience binding for boost::optional
to indicate whether an option is set or not.
Use this to store options passed on the command line directly
in variables for later use. This avoids the need to refer to options
in several locations using a fixed string (like 'help', 'help-gtk', 'nofile',...)

In addition drop a number of obsolete class member variables.
They were leftovers from the conversion to c++ and no longer used.
  • Loading branch information
gjanssens committed Jun 5, 2020
1 parent d14e2cc commit 422dca5
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 110 deletions.
49 changes: 20 additions & 29 deletions gnucash/gnucash-cli.cpp
Expand Up @@ -37,6 +37,7 @@ extern "C" {
}

#include <boost/locale.hpp>
#include <boost/optional.hpp>
#include <iostream>

namespace bl = boost::locale;
Expand All @@ -56,9 +57,11 @@ namespace Gnucash {
void configure_program_options (void);

bool m_add_quotes;
std::string m_run_report;
std::string m_export_type;
std::string m_output_file;
boost::optional <std::string> m_namespace;

boost::optional <std::string> m_run_report;
boost::optional <std::string> m_export_type;
boost::optional <std::string> m_output_file;
};

}
Expand All @@ -73,23 +76,11 @@ Gnucash::GnucashCli::parse_command_line (int argc, char **argv)
{
Gnucash::CoreApp::parse_command_line (argc, argv);

if (m_log_to_filename.empty())
m_log_to_filename.assign("stderr");

m_add_quotes = m_opt_map["add-price-quotes"].as<bool>();

if (m_opt_map.count ("namespace"))
gnc_prefs_set_namespace_regexp(m_opt_map["namespace"].
as<std::string>().c_str());

if (m_opt_map.count ("run-report"))
m_run_report = m_opt_map["run-report"].as<std::string>();

if (m_opt_map.count ("export-type"))
m_export_type = m_opt_map["export-type"].as<std::string>();
if (!m_log_to_filename || m_log_to_filename->empty())
m_log_to_filename = "stderr";

if (m_opt_map.count ("output-file"))
m_output_file = m_opt_map["output-file"].as<std::string>();
if (m_namespace)
gnc_prefs_set_namespace_regexp (m_namespace->c_str());
}

// Define command line options specific to gnucash-cli.
Expand All @@ -98,19 +89,19 @@ Gnucash::GnucashCli::configure_program_options (void)
{
bpo::options_description quotes_options(_("Price Quotes Retrieval Options"));
quotes_options.add_options()
("add-price-quotes", bpo::bool_switch(),
("add-price-quotes", bpo::bool_switch (&m_add_quotes),
_("Add price quotes to given GnuCash datafile."))
("namespace", bpo::value<std::string>(),
("namespace", bpo::value (&m_namespace),
_("Regular expression determining which namespace commodities will be retrieved"));
m_opt_desc->add (quotes_options);

bpo::options_description report_options(_("Report Generation Options"));
report_options.add_options()
("run-report", bpo::value<std::string>(),
("run-report", bpo::value (&m_run_report),
_("Runs a report\n"))
("export-type", bpo::value<std::string>(),
("export-type", bpo::value (&m_export_type),
_("Specify export type\n"))
("output-file", bpo::value<std::string>(),
("output-file", bpo::value (&m_output_file),
_("Output file for report\n"));
m_opt_desc->add (report_options);

Expand All @@ -123,26 +114,26 @@ Gnucash::GnucashCli::start ([[maybe_unused]] int argc, [[maybe_unused]] char **a

if (m_add_quotes)
{
if (m_file_to_load.empty())
if (!m_file_to_load || m_file_to_load->empty())
{
std::cerr << bl::translate("Missing data file parameter") << "\n\n"
<< *m_opt_desc.get();
return 1;
}
else
return Gnucash::add_quotes (m_file_to_load);
return Gnucash::add_quotes (*m_file_to_load);
}

if (!m_run_report.empty())
if (m_run_report && !m_run_report->empty())
{
if (m_file_to_load.empty())
if (!m_file_to_load || m_file_to_load->empty())
{
std::cerr << bl::translate("Missing data file parameter") << "\n\n"
<< *m_opt_desc.get();
return 1;
}
else
return Gnucash::run_report(m_file_to_load, m_run_report,
return Gnucash::run_report(*m_file_to_load, m_run_report,
m_export_type, m_output_file);
}
return 1;
Expand Down
22 changes: 12 additions & 10 deletions gnucash/gnucash-commands.cpp
Expand Up @@ -198,23 +198,25 @@ scm_run_report (void *data,
}

int
Gnucash::add_quotes (const std::string& uri)
Gnucash::add_quotes (const bo_str& uri)
{
if (!uri.empty())
scm_boot_guile (0, nullptr, scm_add_quotes, (void *)&uri);
if (uri && !uri->empty())
scm_boot_guile (0, nullptr, scm_add_quotes, (void *)&(*uri));

return 0;
}

int
Gnucash::run_report (const std::string& file_to_load,
const std::string& run_report,
const std::string& export_type,
const std::string& output_file)
Gnucash::run_report (const bo_str& file_to_load,
const bo_str& run_report,
const bo_str& export_type,
const bo_str& output_file)
{
auto args = run_report_args { file_to_load, run_report,
export_type, output_file };
if (!run_report.empty())
auto args = run_report_args { file_to_load ? *file_to_load : std::string(),
run_report ? *run_report : std::string(),
export_type ? *export_type : std::string(),
output_file ? *output_file : std::string() };
if (run_report && !run_report->empty())
scm_boot_guile (0, nullptr, scm_run_report, &args);

return 0;
Expand Down
13 changes: 8 additions & 5 deletions gnucash/gnucash-commands.hpp
Expand Up @@ -26,14 +26,17 @@
#define GNUCASH_COMMANDS_HPP

#include <string>
#include <boost/optional.hpp>

using bo_str = boost::optional <std::string>;

namespace Gnucash {

int add_quotes (const std::string& uri);
int run_report (const std::string& file_to_load,
const std::string& run_report,
const std::string& export_type,
const std::string& output_file);
int add_quotes (const bo_str& uri);
int run_report (const bo_str& file_to_load,
const bo_str& run_report,
const bo_str& export_type,
const bo_str& output_file);

}
#endif
60 changes: 23 additions & 37 deletions gnucash/gnucash-core-app.cpp
Expand Up @@ -350,14 +350,15 @@ load_user_config(void)


static void
gnc_log_init (std::vector <std::string> &log_flags, std::string &log_to_filename)
gnc_log_init (const boost::optional <std::vector <std::string>> &log_flags,
const boost::optional <std::string> &log_to_filename)
{
if (!log_to_filename.empty())
if (log_to_filename && !log_to_filename->empty())
{
#ifdef __MINGW64__
auto *utf8_filename = g_utf16_to_utf8 (log_to_filename, -1, NULL, NULL, NULL);
auto *utf8_filename = g_utf16_to_utf8 (log_to_filename->c_str(), -1, NULL, NULL, NULL);
#else
auto utf8_filename = log_to_filename.c_str();
auto utf8_filename = log_to_filename->c_str();
#endif

qof_log_init_filename_special (utf8_filename);
Expand Down Expand Up @@ -392,9 +393,9 @@ gnc_log_init (std::vector <std::string> &log_flags, std::string &log_to_filename
qof_log_parse_log_config (log_config_filename);
g_free (log_config_filename);

if (!log_flags.empty())
if (log_flags && !log_flags->empty())
{
for (auto log_flag : log_flags)
for (auto log_flag : *log_flags)
{
if (log_flag.empty () ||
log_flag[0] == '=' ||
Expand Down Expand Up @@ -516,9 +517,9 @@ Gnucash::CoreApp::CoreApp (const char* app_name)
m_app_name = std::string(app_name);

// Now that gettext is properly initialized, set our help tagline.
tagline = bl::translate("- GnuCash, accounting for personal and small business finance").str(gnc_get_locale());
m_tagline = bl::translate("- GnuCash, accounting for personal and small business finance").str(gnc_get_locale());
m_opt_desc = std::make_unique<bpo::options_description>
((bl::format (bl::gettext ("{1} [options] [datafile]")) % m_app_name).str() + std::string(" ") + tagline);
((bl::format (bl::gettext ("{1} [options] [datafile]")) % m_app_name).str() + std::string(" ") + m_tagline);
add_common_program_options();
}

Expand All @@ -544,7 +545,7 @@ Gnucash::CoreApp::parse_command_line (int argc, char **argv)
exit(1);
}

if (m_opt_map["version"].as<bool>())
if (m_show_version)
{
bl::format rel_fmt (bl::translate ("GnuCash {1}"));
bl::format dev_fmt (bl::translate ("GnuCash {1} development version"));
Expand All @@ -558,32 +559,17 @@ Gnucash::CoreApp::parse_command_line (int argc, char **argv)
exit(0);
}

if (m_opt_map["help"].as<bool>())
if (m_show_help)
{
std::cout << *m_opt_desc.get() << "\n";
exit(0);
}

gnc_prefs_set_debugging (m_opt_map["debug"].as<bool>());
gnc_prefs_set_extra (m_opt_map["extra"].as<bool>());
gnc_prefs_set_debugging (m_debug);
gnc_prefs_set_extra (m_extra);

if (m_opt_map.count ("gsettings-prefix"))
gnc_gsettings_set_prefix (m_opt_map["gsettings-prefix"].
as<std::string>().c_str());

if (m_opt_map.count ("log"))
m_log_flags = m_opt_map["log"].
as<std::vector <std::string>>();

if (m_opt_map.count ("logto"))
m_log_to_filename = m_opt_map["logto"].
as<std::string>().c_str();

if (m_opt_map.count ("input-file"))
m_file_to_load = m_opt_map["input-file"].as<std::string>();

if (args_remaining)
file_to_load = args_remaining[0];
if (m_gsettings_prefix)
gnc_gsettings_set_prefix (m_gsettings_prefix->c_str());
}

/* Define command line options common to all gnucash binaries. */
Expand All @@ -592,21 +578,21 @@ Gnucash::CoreApp::add_common_program_options (void)
{
bpo::options_description common_options(_("Common Options"));
common_options.add_options()
("help,h", bpo::bool_switch(),
("help,h", bpo::bool_switch (&m_show_help),
_("Show this help message"))
("version,v", bpo::bool_switch(),
("version,v", bpo::bool_switch (&m_show_version),
_("Show GnuCash version"))
("debug", bpo::bool_switch(),
("debug", bpo::bool_switch (&m_debug),
_("Enable debugging mode: provide deep detail in the logs.\nThis is equivalent to: --log \"=info\" --log \"qof=info\" --log \"gnc=info\""))
("extra", bpo::bool_switch(),
("extra", bpo::bool_switch(&m_extra),
_("Enable extra/development/debugging features."))
("log", bpo::value< std::vector<std::string> >(),
("log", bpo::value (&m_log_flags),
_("Log level overrides, of the form \"modulename={debug,info,warn,crit,error}\"\nExamples: \"--log qof=debug\" or \"--log gnc.backend.file.sx=info\"\nThis can be invoked multiple times."))
("logto", bpo::value<std::string>(),
("logto", bpo::value (&m_log_to_filename),
_("File to log into; defaults to \"/tmp/gnucash.trace\"; can be \"stderr\" or \"stdout\"."))
("gsettings-prefix", bpo::value<std::string>(),
("gsettings-prefix", bpo::value (&m_gsettings_prefix),
_("Set the prefix for gsettings schemas for gsettings queries. This can be useful to have a different settings tree while debugging."))
("input-file", bpo::value<std::string>(),
("input-file", bpo::value (&m_file_to_load),
_("[datafile]"));

m_pos_opt_desc.add("input-file", -1);
Expand Down
24 changes: 10 additions & 14 deletions gnucash/gnucash-core-app.hpp
Expand Up @@ -27,6 +27,7 @@
#ifdef __MINGW32__
#undef _GLIBCXX_USE_C99_MATH_TR1 // Avoid cmath missing function decl.
#endif
#include <boost/optional.hpp>
#include <boost/program_options.hpp>
#include <string>
#include <vector>
Expand All @@ -45,11 +46,10 @@ class CoreApp
void start (void);

protected:
int gtk_show_help = 0;
std::string m_app_name;
std::string tagline;
std::string m_file_to_load;
std::string m_log_to_filename;
std::string m_tagline;
boost::optional <std::string> m_log_to_filename;
boost::optional <std::string> m_file_to_load;

std::unique_ptr<bpo::options_description> m_opt_desc;
bpo::variables_map m_opt_map;
Expand All @@ -59,17 +59,13 @@ class CoreApp
void add_common_program_options (void);

/* Command-line option variables */
std::vector <std::string> m_log_flags;
bool m_show_help = false;
bool m_show_version = false;
bool m_debug = false;
bool m_extra = false;
boost::optional <std::string> m_gsettings_prefix;
boost::optional <std::vector <std::string>> m_log_flags;

int gnucash_show_version = 0;
int debugging = 0;
int extra = 0;
int nofile = 0;
const char *gsettings_prefix = nullptr;
const char *add_quotes_file = nullptr;
char *namespace_regexp = nullptr;
const char *file_to_load = nullptr;
char **args_remaining = nullptr;
char *sys_locale = nullptr;
};

Expand Down

0 comments on commit 422dca5

Please sign in to comment.