diff --git a/gnucash/gnucash-cli.cpp b/gnucash/gnucash-cli.cpp index 4b6b0643e3a..53cbb5ee419 100644 --- a/gnucash/gnucash-cli.cpp +++ b/gnucash/gnucash-cli.cpp @@ -114,10 +114,10 @@ Gnucash::GnucashCli::configure_program_options (void) bpo::options_description cli_options(_("Scripting and/or Interactive Session Options")); cli_options.add_options() - ("script,S", bpo::value (&m_script), "Script to run") - ("interactive,I", bpo::bool_switch (&m_interactive), "Interactive session") - ("language,L", bpo::value (&m_language)->default_value("guile"), "Specify language for script or interactive session; guile (default) or python") - ("readwrite,W", bpo::bool_switch (&m_open_readwrite), "Open datafile read-write for script and/or interactive session"); + ("script,S", bpo::value (&m_script), _("Script to run")) + ("interactive,I", bpo::bool_switch (&m_interactive), _("Interactive session")) + ("language,L", bpo::value (&m_language)->default_value("guile"), _("Specify language for script or interactive session; guile (default) or python")) + ("readwrite,W", bpo::bool_switch (&m_open_readwrite), _("Open datafile read-write for script and/or interactive session")); m_opt_desc_display->add (cli_options); m_opt_desc_all.add (cli_options); diff --git a/gnucash/gnucash-commands.cpp b/gnucash/gnucash-commands.cpp index 03abc73bb50..7daa0c4048f 100644 --- a/gnucash/gnucash-commands.cpp +++ b/gnucash/gnucash-commands.cpp @@ -119,12 +119,14 @@ get_line (const char* prompt) static std::string get_choice (const char* prompt, const std::vector choices) { - while (true) + std::string response; + do { - auto response = get_line (prompt); - if (std::find (choices.begin(), choices.end(), response) != choices.end()) - return response; + response = get_line (prompt); } + while (std::none_of (choices.begin(), choices.end(), + [&response](auto& choice) { return choice == response; } )); + return response; } struct scripting_args @@ -219,11 +221,11 @@ load_file (const std::string& m_file_to_load, bool m_open_readwrite) break; } case ERR_BACKEND_READONLY: - PWARN ("File is readonly. Cannot open read-write"); + std::cerr << _("File is readonly. Cannot open read-write") << std::endl; mode = SESSION_READ_ONLY; break; default: - PWARN ("Unknown error. Abort."); + std::cerr << _("Unknown error. Abort.") << std::endl; scm_cleanup_and_exit_with_failure (session); } } @@ -558,13 +560,10 @@ Gnucash::run_scripting (int argc, char **argv, errors.push_back (_ ("--readwrite: missing datafile!")); if (m_script && (!boost::filesystem::is_regular_file (*m_script))) - { - auto str = g_strdup_printf (_("--script: %s is not a file"), m_script->c_str()); - errors.push_back (str); - g_free (str); - } + errors.push_back ((bl::format (_("--script: {1} is not a file")) % *m_script).str()); - if (std::find (languages.begin(), languages.end(), m_language) == languages.end()) + if (std::none_of (languages.begin(), languages.end(), + [&m_language](auto& lang){ return m_language == lang; })) errors.push_back (_ ("--language: must be 'python' or 'guile'")); #ifndef HAVE_PYTHON_H else if (m_language == "python") @@ -580,17 +579,13 @@ Gnucash::run_scripting (int argc, char **argv, } std::vector newArgv { argv[0] }; - bool foundDoubleDash = false; + std::vector argv_vec (argv, argv + argc); + auto is_double_dash = [](char* s){ return g_strcmp0 (s,"--") == 0; }; // all arguments after "--" will be sent to the guile/python // script/REPL. - for (int i = 0; i < argc; i++) - { - if (foundDoubleDash) - newArgv.push_back (argv[i]); - else if (!g_strcmp0 (argv[i], "--")) - foundDoubleDash = true; - } + auto match = std::find_if (argv_vec.begin(), argv_vec.end(), is_double_dash); + std::copy (match, argv_vec.end(), std::back_inserter(newArgv)); gnc_prefs_init (); gnc_ui_util_init(); @@ -611,44 +606,48 @@ Gnucash::run_scripting (int argc, char **argv, PyConfig_InitPythonConfig(&config); PyStatus status = PyConfig_SetBytesArgv(&config, newArgv.size(), newArgv.data()); - if (PyStatus_Exception(status)) - goto exception; + try + { + if (PyStatus_Exception(status)) + throw; - status = Py_InitializeFromConfig(&config); - if (PyStatus_Exception(status)) - goto exception; + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) + throw; - PyConfig_Clear(&config); + PyConfig_Clear(&config); - if (m_script) - { - auto script_filename = m_script->c_str(); - PINFO ("Running python script %s...", script_filename); - auto fp = fopen (script_filename, "r"); - if (fp) - PyRun_SimpleFileEx (fp, script_filename, 1); - else - std::cerr << bl::format (_("Unable to load Python script (unable to open {1})")) % script_filename - << std::endl; + if (m_script) + { + auto script_filename = m_script->c_str(); + PINFO ("Running python script %s...", script_filename); + auto fp = fopen (script_filename, "r"); + if (fp) + PyRun_SimpleFileEx (fp, script_filename, 1); + else + std::cerr << bl::format (_("Unable to load Python script {1}")) % script_filename + << std::endl; + } + if (m_interactive) + { + std::cout << _("Welcome to Gnucash Interactive Python Session") << std::endl; + PyRun_InteractiveLoop (stdin, "foo"); + } + Py_Finalize(); + cleanup_and_exit_with_save (&args); } - if (m_interactive) + catch (const std::exception&) { - std::cout << _("Welcome to Gnucash Interactive Python Session") << std::endl; - PyRun_InteractiveLoop (stdin, "foo"); - } - Py_Finalize(); - cleanup_and_exit_with_save (&args); + if (qof_book_session_not_saved (gnc_get_current_book())) + std::cerr << _("Book is readonly. Unsaved changes will be lost.") << std::endl; + gnc_clear_current_session (); - exception: - if (qof_book_session_not_saved (gnc_get_current_book())) - std::cerr << _("Book is readonly. Unsaved changes will be lost.") << std::endl; - gnc_clear_current_session (); + PyConfig_Clear(&config); + if (PyStatus_IsExit(status)) + gnc_shutdown_cli (status.exitcode); - PyConfig_Clear(&config); - if (PyStatus_IsExit(status)) - return status.exitcode; - - Py_ExitStatusException(status); + Py_ExitStatusException(status); + } } #endif return 0; // never reached diff --git a/gnucash/gnucash-core-app.cpp b/gnucash/gnucash-core-app.cpp index f55baa64c17..fe6a91553dc 100644 --- a/gnucash/gnucash-core-app.cpp +++ b/gnucash/gnucash-core-app.cpp @@ -220,10 +220,9 @@ Gnucash::CoreApp::parse_command_line (int argc, char **argv) try { // don't process args on and after "--" - for (auto i = 0; i < argc; ++i) - if (!g_strcmp0 (argv[i], "--")) - argc = i; // following this statement, the for loop exit - // condition i < argc will be satisfied + std::vector argv_vec (argv, argv + argc); + auto match = std::find(argv_vec.begin(), argv_vec.end(), "--"); + argc = std::distance (argv_vec.begin(), match); bpo::store (bpo::command_line_parser (argc, argv). options (m_opt_desc_all).positional(m_pos_opt_desc).run(), m_opt_map);