Skip to content
This repository was archived by the owner on Jun 25, 2020. It is now read-only.

Commit 9bdc0c9

Browse files
committed
feature: new implementation
1 parent 7e2b6a8 commit 9bdc0c9

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

src/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ endif()
2828
find_package(LibClang REQUIRED)
2929
find_package(Boost 1.54 COMPONENTS thread log regex system filesystem REQUIRED)
3030
find_package(ASPELL REQUIRED)
31+
find_package(PythonLibs 3 REQUIRED)
3132
set(LIBCLANGMM_INCLUDE_DIR ../libclangmm/src)
3233
set(TINY_PROCESS_INCLUDE_DIR ../tiny-process-library)
34+
set(PYBIND11_INCLUDE_DIR ../pybind11/include)
3335

3436
string(REPLACE libclang liblldb LIBLLDB_LIBRARIES "${LIBCLANG_LIBRARIES}")
3537
if(EXISTS "${LIBLLDB_LIBRARIES}")
@@ -48,6 +50,7 @@ endif()
4850
include(FindPkgConfig)
4951
pkg_check_modules(GTKMM gtkmm-3.0 REQUIRED)
5052
pkg_check_modules(GTKSVMM gtksourceviewmm-3.0 REQUIRED)
53+
pkg_check_modules(PYGOBJECT pygobject-3.0 REQUIRED)
5154

5255
set(global_includes
5356
${Boost_INCLUDE_DIRS}
@@ -57,6 +60,9 @@ set(global_includes
5760
${LIBCLANGMM_INCLUDE_DIR}
5861
${ASPELL_INCLUDE_DIR}
5962
${TINY_PROCESS_INCLUDE_DIR}
63+
${PYBIND11_INCLUDE_DIR}
64+
${PYTHON_INCLUDE_DIRS}
65+
${PYGOBJECT_INCLUDE_DIRS}
6066
)
6167

6268
set(global_libraries
@@ -66,6 +72,8 @@ set(global_libraries
6672
${Boost_LIBRARIES}
6773
${ASPELL_LIBRARIES}
6874
${LIBLLDB_LIBRARIES}
75+
${PYTHON_LIBRARIES}
76+
${PYGOBJECT_LIBRARIES}
6977
)
7078

7179
set(project_files
@@ -95,6 +103,8 @@ set(project_files
95103
project.h
96104
project_build.h
97105
project_build.cc
106+
python_interpreter.cc
107+
python_interpreter.h
98108
selectiondialog.cc
99109
selectiondialog.h
100110
source.cc

src/python_interpreter.cc

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#include "python_interpreter.h"
2+
#include "notebook.h"
3+
#include "config.h"
4+
#include <iostream>
5+
#include <pygobject.h>
6+
7+
inline pybind11::module pyobject_from_gobj(gpointer ptr){
8+
auto obj=G_OBJECT(ptr);
9+
if(obj)
10+
return pybind11::module(pygobject_new(obj), false);
11+
return pybind11::module(Py_None, false);
12+
}
13+
14+
PythonInterpreter::PythonInterpreter(){
15+
auto init_juci_api=[](){
16+
pybind11::module(pygobject_init(-1,-1,-1), false);
17+
pybind11::module api("jucpp", "Python bindings for juCi++");
18+
api.def("get_current_text_buffer", [](){
19+
auto view=Notebook::get().get_current_view();
20+
if(view)
21+
return pyobject_from_gobj(view->gobj());
22+
return pybind11::module(Py_None, false);
23+
});
24+
return api.ptr();
25+
};
26+
PyImport_AppendInittab("jucipp", init_juci_api);
27+
Py_Initialize();
28+
Config::get().load();
29+
}
30+
31+
pybind11::module PythonInterpreter::get_loaded_module(const std::string &module_name){
32+
return pybind11::module(PyImport_AddModule(module_name.c_str()), true);
33+
}
34+
35+
pybind11::module PythonInterpreter::import(const std::string &module_name){
36+
return pybind11::module(PyImport_ImportModule(module_name.c_str()), false);
37+
}
38+
39+
void PythonInterpreter::add_path(const boost::filesystem::path &path){
40+
std::wstring sys_path(Py_GetPath());
41+
if(!sys_path.empty())
42+
#ifdef _WIN32
43+
sys_path += ';';
44+
#else
45+
sys_path += ':';
46+
#endif
47+
sys_path += path.generic_wstring();
48+
Py_SetPath(sys_path.c_str());
49+
}
50+
51+
PythonInterpreter::~PythonInterpreter(){
52+
auto err=PythonError();
53+
if(Py_IsInitialized())
54+
Py_Finalize();
55+
if(err)
56+
std::cerr << std::string(err) << std::endl;
57+
}
58+
59+
PythonError::PythonError(){
60+
pybind11::object error(PyErr_Occurred(), false);
61+
if(error){
62+
PyObject *exception,*value,*traceback;
63+
PyErr_Fetch(&exception,&value,&traceback);
64+
PyErr_NormalizeException(&exception,&value,&traceback);
65+
try{
66+
exp=std::string(pybind11::object(exception,false).str());
67+
val=std::string(pybind11::object(value,false).str());
68+
trace=std::string(pybind11::object(traceback,false).str());
69+
} catch (const std::runtime_error &e){
70+
exp=e.what();
71+
}
72+
}
73+
}
74+
75+
PythonError::operator std::string(){
76+
return exp + "\n" + val + "\n" + trace;
77+
}
78+
79+
PythonError::operator bool(){
80+
return !exp.empty();
81+
}

src/python_interpreter.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#ifndef JUCI_PYTHON_INTERPRETER_H_
2+
#define JUCI_PYTHON_INTERPRETER_H_
3+
4+
#include <pybind11/pybind11.h>
5+
#include <boost/filesystem/path.hpp>
6+
7+
#include <iostream>
8+
using namespace std;
9+
10+
class PythonInterpreter {
11+
private:
12+
PythonInterpreter();
13+
~PythonInterpreter();
14+
wchar_t *argv;
15+
public:
16+
static PythonInterpreter& get(){
17+
static PythonInterpreter singleton;
18+
return singleton;
19+
}
20+
pybind11::module get_loaded_module(const std::string &module_name);
21+
pybind11::module import(const std::string &module_name);
22+
void add_path(const boost::filesystem::path &path);
23+
};
24+
25+
class PythonError {
26+
public:
27+
PythonError();
28+
operator std::string();
29+
operator bool();
30+
std::string exp, val, trace;
31+
};
32+
33+
#endif // JUCI_PYTHON_INTERPRETER_H_

0 commit comments

Comments
 (0)