From 3685e5de736fde4a5cefdb14ac8f2b7d97ad093b Mon Sep 17 00:00:00 2001 From: Geert Janssens Date: Thu, 11 Feb 2021 16:05:05 +0100 Subject: [PATCH] Factor out the async call to perl This will allow us to reuse it for several F::Q commands, like check, fetch,... --- libgnucash/app-utils/gnc-quotes.cpp | 93 ++++++++++++++++++----------- libgnucash/app-utils/gnc-quotes.hpp | 13 +++- 2 files changed, 69 insertions(+), 37 deletions(-) diff --git a/libgnucash/app-utils/gnc-quotes.cpp b/libgnucash/app-utils/gnc-quotes.cpp index 0d496aa7c5..ea2b399b26 100644 --- a/libgnucash/app-utils/gnc-quotes.cpp +++ b/libgnucash/app-utils/gnc-quotes.cpp @@ -68,45 +68,20 @@ GncQuotes::check (void) m_error_msg.clear(); m_cmd_result = 0; - auto perl_executable = bp::search_path("perl"); //or get it from somewhere else. + auto perl_executable = bp::search_path("perl"); auto fq_check = std::string(gnc_path_get_bindir()) + "/gnc-fq-check"; + StrVec args { "-w", fq_check }; - try - { - std::future > output, error; - boost::asio::io_service svc; + auto cmd_out = run_cmd (perl_executable.string(), args, StrVec()); - bp::child process (perl_executable, "-w", fq_check, bp::std_out > output, bp::std_err > error, svc); - svc.run(); - process.wait(); + for (auto line : cmd_out.first) + if (m_version.empty()) + std::swap (m_version, line); + else + m_sources.push_back (std::move(line)); - { - auto raw = output.get(); - std::vector data; - std::string line; - bio::stream_buffer sb(raw.data(), raw.size()); - std::istream is(&sb); - - while (std::getline(is, line) && !line.empty()) - if (m_version.empty()) - std::swap (m_version, line); - else - m_sources.push_back (std::move(line)); - - raw = error.get(); - bio::stream_buffer eb(raw.data(), raw.size()); - std::istream es(&eb); - - while (std::getline(es, line) && !line.empty()) - m_error_msg.append(std::move(line) + "\n"); - } - m_cmd_result = process.exit_code(); - } - catch (std::exception &e) - { - m_cmd_result = -1; - m_error_msg = e.what(); - }; + for (auto line : cmd_out.second) + m_error_msg.append(std::move(line) + "\n"); if (m_cmd_result == 0) std::sort (m_sources.begin(), m_sources.end()); @@ -172,6 +147,54 @@ format_quotes (const std::vector) } +CmdOutput +GncQuotes::run_cmd (std::string cmd_name, StrVec args, StrVec input_vec) +{ + StrVec out_vec, err_vec; + + try + { + std::future > out_buf, err_buf; + boost::asio::io_service svc; + + auto input_buf = bp::buffer (input_vec); + bp::child process (cmd_name, args, + bp::std_out > out_buf, + bp::std_err > err_buf, + bp::std_in < input_buf, + svc); + svc.run(); + process.wait(); + + { + auto raw = out_buf.get(); + std::vector data; + std::string line; + bio::stream_buffer sb(raw.data(), raw.size()); + std::istream is(&sb); + + while (std::getline(is, line) && !line.empty()) + out_vec.push_back (std::move(line)); + + raw = err_buf.get(); + bio::stream_buffer eb(raw.data(), raw.size()); + std::istream es(&eb); + + while (std::getline(es, line) && !line.empty()) + err_vec.push_back (std::move(line)); + } + m_cmd_result = process.exit_code(); + } + catch (std::exception &e) + { + m_cmd_result = -1; + m_error_msg = e.what(); + }; + + return CmdOutput (std::move(out_vec), std::move(err_vec)); +} + + /******************************************************************** * gnc_quotes_get_quotable_commodities * list commodities in a given namespace that get price quotes diff --git a/libgnucash/app-utils/gnc-quotes.hpp b/libgnucash/app-utils/gnc-quotes.hpp index 504e620432..792a9d12d3 100644 --- a/libgnucash/app-utils/gnc-quotes.hpp +++ b/libgnucash/app-utils/gnc-quotes.hpp @@ -31,10 +31,13 @@ extern "C" { #include } -using QuoteSources = std::vector; +using StrVec = std::vector ; +using QuoteSources = StrVec; +using CmdOutput = std::pair ; const std::string not_found = std::string ("Not Found"); + class GncQuotes { public: @@ -51,8 +54,14 @@ public: GList* sources_as_glist (); private: - // Function to check if Finance::Quote is properly installed + // Check if Finance::Quote is properly installed void check (void); + // Run the command specified. Returns two vectors for further processing by the caller + // - one with the contents of stdout + // - one with the contents of stderr + // Will also set m_cmd_result + CmdOutput run_cmd (std::string cmd_name, StrVec args, StrVec input_vec); + std::string m_version; QuoteSources m_sources;