Allow loading and running Python files before GUI starts

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-06-07 08:56:54 +02:00
parent c18f0b1c22
commit bdd9313582
5 changed files with 64 additions and 53 deletions

View File

@ -22,6 +22,7 @@
#include "design.h" #include "design.h"
#include "chip.h" #include "chip.h"
#include "pybindings.h" #include "pybindings.h"
#include "emb.h"
// Required to determine concatenated module name (which differs for different archs) // Required to determine concatenated module name (which differs for different archs)
#define PASTER(x, y) x ## _ ## y #define PASTER(x, y) x ## _ ## y
@ -36,43 +37,52 @@
void arch_wrap_python(); void arch_wrap_python();
BOOST_PYTHON_MODULE (MODULE_NAME) { BOOST_PYTHON_MODULE (MODULE_NAME) {
arch_wrap_python(); arch_wrap_python();
} }
void arch_appendinittab() void arch_appendinittab() {
{ PyImport_AppendInittab(TOSTRING(MODULE_NAME), PYINIT_MODULE_NAME);
PyImport_AppendInittab(TOSTRING(MODULE_NAME), PYINIT_MODULE_NAME);
} }
void execute_python_file(const char *executable, const char* python_file) static wchar_t *program;
{
wchar_t *program = Py_DecodeLocale(executable, NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode executable filename\n");
exit(1);
}
try
{
PyImport_AppendInittab(TOSTRING(MODULE_NAME), PYINIT_MODULE_NAME);
Py_SetProgramName(program);
Py_Initialize();
FILE* fp = fopen(python_file, "r"); void init_python(const char *executable) {
if (fp == NULL) { program = Py_DecodeLocale(executable, NULL);
fprintf(stderr, "Fatal error: file not found %s\n",python_file); if (program == NULL) {
exit(1); fprintf(stderr, "Fatal error: cannot decode executable filename\n");
} exit(1);
PyRun_SimpleFile(fp , python_file); }
fclose(fp); try {
PyImport_AppendInittab(TOSTRING(MODULE_NAME), PYINIT_MODULE_NAME);
Py_Finalize(); emb::append_inittab();
PyMem_RawFree(program); Py_SetProgramName(program);
} Py_Initialize();
catch(boost::python::error_already_set const &) } catch (boost::python::error_already_set const &) {
{ // Parse and output the exception
// Parse and output the exception std::string perror_str = parse_python_exception();
std::string perror_str = parse_python_exception(); std::cout << "Error in Python: " << perror_str << std::endl;
std::cout << "Error in Python: " << perror_str << std::endl; }
} }
void deinit_python() {
Py_Finalize();
PyMem_RawFree(program);
}
void execute_python_file(const char *python_file) {
try {
FILE *fp = fopen(python_file, "r");
if (fp == NULL) {
fprintf(stderr, "Fatal error: file not found %s\n", python_file);
exit(1);
}
PyRun_SimpleFile(fp, python_file);
fclose(fp);
}
catch (boost::python::error_already_set const &) {
// Parse and output the exception
std::string perror_str = parse_python_exception();
std::cout << "Error in Python: " << perror_str << std::endl;
}
} }

View File

@ -26,7 +26,6 @@
#include <boost/python/suite/indexing/vector_indexing_suite.hpp> #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp> #include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp> #include <boost/python/suite/indexing/map_indexing_suite.hpp>
using namespace boost::python; using namespace boost::python;
/* /*
A wrapper for a Pythonised nextpnr Iterator. The actual class wrapped is a A wrapper for a Pythonised nextpnr Iterator. The actual class wrapped is a
@ -79,7 +78,10 @@ struct range_wrapper {
#define WRAP_RANGE(t) range_wrapper<t##Range>().wrap(#t "Range", #t "Iterator") #define WRAP_RANGE(t) range_wrapper<t##Range>().wrap(#t "Range", #t "Iterator")
void execute_python_file(const char *executable, const char* python_file); void init_python(const char *executable);
void deinit_python();
void execute_python_file(const char* python_file);
std::string parse_python_exception(); std::string parse_python_exception();
void arch_appendinittab(); void arch_appendinittab();

View File

@ -11,9 +11,6 @@ MainWindow::MainWindow(QWidget *parent) :
ui(new Ui::MainWindow) ui(new Ui::MainWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
emb::append_inittab();
arch_appendinittab();
Py_Initialize();
PyImport_ImportModule("emb"); PyImport_ImportModule("emb");
write = [this] (std::string s) { write = [this] (std::string s) {
@ -27,7 +24,6 @@ MainWindow::MainWindow(QWidget *parent) :
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
Py_Finalize();
delete ui; delete ui;
} }

View File

@ -45,7 +45,7 @@ void svg_dump_el(const GraphicElement &el)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
namespace po = boost::program_options; namespace po = boost::program_options;
int rc = 0;
std::string str; std::string str;
po::options_description options("Allowed options"); po::options_description options("Allowed options");
@ -122,15 +122,7 @@ int main(int argc, char *argv[])
chipArgs.type = ChipArgs::UP5K; chipArgs.type = ChipArgs::UP5K;
Design design(chipArgs); Design design(chipArgs);
init_python(argv[0]);
if (vm.count("gui"))
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
if (vm.count("test")) if (vm.count("test"))
{ {
@ -216,8 +208,17 @@ int main(int argc, char *argv[])
if (vm.count("file")) if (vm.count("file"))
{ {
std::string filename = vm["file"].as<std::string>(); std::string filename = vm["file"].as<std::string>();
execute_python_file(argv[0],filename.c_str()); execute_python_file(filename.c_str());
} }
return 0; if (vm.count("gui"))
{
QApplication a(argc, argv);
MainWindow w;
w.show();
rc = a.exec();
}
deinit_python();
return rc;
} }

2
python/functions.py Normal file
View File

@ -0,0 +1,2 @@
def test_function():
print("Hello World!")