Skip to content

Commit

Permalink
[gnucash-commands.cpp] don't use m_, extract python funcs, modify argv
Browse files Browse the repository at this point in the history
now argv will have either datafile or "" -- this is accepted by python
and guile alike
  • Loading branch information
christopherlam committed Oct 27, 2023
1 parent 1c036b1 commit 403728b
Showing 1 changed file with 61 additions and 56 deletions.
117 changes: 61 additions & 56 deletions gnucash/gnucash-commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,81 +577,84 @@ run_guile_cli (void *data, [[maybe_unused]] int argc, [[maybe_unused]] char **ar
}


#ifdef HAVE_PYTHON_H
static void
python_cleanup (PyConfig& config, PyStatus& status)
{
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);

Py_ExitStatusException(status);
}

static void
run_python_cli (int argc, char **argv, scripting_args* args)
{
#ifdef HAVE_PYTHON_H
PyConfig config;
PyConfig_InitPythonConfig(&config);

PyStatus status = PyConfig_SetBytesArgv(&config, argc, argv);
try
{
if (PyStatus_Exception(status))
throw;
if (PyStatus_Exception(status))
python_cleanup (config, status);

status = Py_InitializeFromConfig(&config);
if (PyStatus_Exception(status))
throw;
status = Py_InitializeFromConfig(&config);
if (PyStatus_Exception(status))
python_cleanup (config, status);

PyConfig_Clear(&config);
PyConfig_Clear(&config);

if (args->script)
{
auto script_filename = args->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 (args->interactive)
if (args->script)
{
auto script_filename = args->script->c_str();
PINFO ("Running python script %s...", script_filename);
auto fp = fopen (script_filename, "rb");
if (!fp)
std::cerr << bl::format (_("Unable to load Python script {1}")) % script_filename
<< std::endl;
else if (PyRun_SimpleFileEx (fp, script_filename, 1) != 0)
{
std::cout << _("Welcome to Gnucash Interactive Python Session") << std::endl;
PyRun_InteractiveLoop (stdin, "foo");
std::cerr << bl::format (_("Python script {1} execution failed.")) % script_filename;
Py_Finalize();
python_cleanup (config, status);
}
Py_Finalize();
cleanup_and_exit_with_save ();
}
catch (const std::exception&)
if (args->interactive)
{
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);

Py_ExitStatusException(status);
std::cout << _("Welcome to Gnucash Interactive Python Session") << std::endl;
PyRun_InteractiveLoop (stdin, "foo");
}
#endif
Py_Finalize();
cleanup_and_exit_with_save ();
}
#endif

int
Gnucash::run_scripting (std::vector<std::string> m_script_args,
const bo_str& m_file_to_load,
std::string& m_language,
const bo_str& m_script,
bool m_open_readwrite,
bool m_interactive)
Gnucash::run_scripting (std::vector<std::string> script_args,
const bo_str& file_to_load,
std::string& language,
const bo_str& script,
bool open_readwrite,
bool interactive)
{
std::vector<std::string> errors;
static const std::vector<std::string> languages = { "guile", "python" };

if (m_open_readwrite && !m_file_to_load)
if (open_readwrite && !file_to_load)
errors.push_back (_ ("--readwrite: missing datafile!"));

if (m_script && (!boost::filesystem::is_regular_file (*m_script)))
errors.push_back ((bl::format (_("--script: {1} is not a file")) % *m_script).str());
if (script && (!boost::filesystem::is_regular_file (*script)))
errors.push_back ((bl::format (_("--script: {1} is not a file")) % *script).str());

if (std::none_of (languages.begin(), languages.end(),
[&m_language](auto& lang){ return m_language == lang; }))
[&language](auto& lang){ return language == lang; }))
errors.push_back (_ ("--language: must be 'python' or 'guile'"));
#ifndef HAVE_PYTHON_H
else if (m_language == "python")
else if (language == "python")
errors.push_back (_("--language: python wasn't compiled in this build"));
#endif

Expand All @@ -663,28 +666,30 @@ Gnucash::run_scripting (std::vector<std::string> m_script_args,
gnc_shutdown_cli (1);
}

std::vector<const char*> newArgv {"gnucash-cli"};
std::transform (m_script_args.begin(), m_script_args.end(), std::back_inserter(newArgv),
std::vector<const char*> newArgv =
{ "gnucash-cli", file_to_load ? file_to_load->c_str() : ""};
std::transform (script_args.begin(), script_args.end(), std::back_inserter(newArgv),
[](const std::string& s) { return s.c_str(); });
// note the vector<const char*> is valid as long as m_script_args's strings are not damaged!
// note the vector<const char*> is valid as long as script_args's strings are not damaged!

gnc_prefs_init ();
gnc_ui_util_init();
if (m_file_to_load)
load_file (*m_file_to_load, m_open_readwrite);
if (file_to_load && boost::filesystem::is_regular_file (*file_to_load))
load_file (*file_to_load, open_readwrite);

scripting_args args { m_script, m_interactive };
if (m_language == "guile")
scripting_args args { script, interactive };
if (language == "guile")
{
scm_boot_guile (newArgv.size(), (char**)newArgv.data(), run_guile_cli, &args);
return 0; // never reached...
}
else if (m_language == "python")
#ifdef HAVE_PYTHON_H
else if (language == "python")
{
run_python_cli (newArgv.size(), (char**)newArgv.data(), &args);
return 0; // never reached...
}

#endif

return 0; // never reached
}

0 comments on commit 403728b

Please sign in to comment.