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

Commit

Permalink
feature: new implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
zalox committed Apr 8, 2016
1 parent 7e2b6a8 commit d82ae2b
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ endif()
find_package(LibClang REQUIRED)
find_package(Boost 1.54 COMPONENTS thread log regex system filesystem REQUIRED)
find_package(ASPELL REQUIRED)
find_package(PythonLibs 3 REQUIRED)
set(LIBCLANGMM_INCLUDE_DIR ../libclangmm/src)
set(TINY_PROCESS_INCLUDE_DIR ../tiny-process-library)
set(PYBIND11_INCLUDE_DIR ../pybind11/include)

string(REPLACE libclang liblldb LIBLLDB_LIBRARIES "${LIBCLANG_LIBRARIES}")
if(EXISTS "${LIBLLDB_LIBRARIES}")
Expand All @@ -48,6 +50,7 @@ endif()
include(FindPkgConfig)
pkg_check_modules(GTKMM gtkmm-3.0 REQUIRED)
pkg_check_modules(GTKSVMM gtksourceviewmm-3.0 REQUIRED)
pkg_check_modules(PYGOBJECT pygobject-3.0 REQUIRED)

set(global_includes
${Boost_INCLUDE_DIRS}
Expand All @@ -57,6 +60,9 @@ set(global_includes
${LIBCLANGMM_INCLUDE_DIR}
${ASPELL_INCLUDE_DIR}
${TINY_PROCESS_INCLUDE_DIR}
${PYBIND11_INCLUDE_DIR}
${PYTHON_INCLUDE_DIRS}
${PYGOBJECT_INCLUDE_DIRS}
)

set(global_libraries
Expand All @@ -66,6 +72,8 @@ set(global_libraries
${Boost_LIBRARIES}
${ASPELL_LIBRARIES}
${LIBLLDB_LIBRARIES}
${PYTHON_LIBRARIES}
${PYGOBJECT_LIBRARIES}
)

set(project_files
Expand Down Expand Up @@ -95,6 +103,8 @@ set(project_files
project.h
project_build.h
project_build.cc
python_interpreter.cc
python_interpreter.h
selectiondialog.cc
selectiondialog.h
source.cc
Expand Down
99 changes: 99 additions & 0 deletions src/python_interpreter.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include "python_interpreter.h"
#include "notebook.h"
#include "config.h"
#include <iostream>
#include <pygobject.h>

inline pybind11::module pyobject_from_gobj(gpointer ptr){
auto obj=G_OBJECT(ptr);
if(obj)
return pybind11::module(pygobject_new(obj), false);
return pybind11::module(Py_None, false);
}

PythonInterpreter::PythonInterpreter(){
auto init_juci_api=[](){
pybind11::module(pygobject_init(-1,-1,-1), false);
pybind11::module api("jucpp", "Python bindings for juCi++");
api.def("get_current_text_buffer", [](){
auto view=Notebook::get().get_current_view();
if(view)
return pyobject_from_gobj(view->gobj());
return pybind11::module(Py_None, false);
});
return api.ptr();
};
PyImport_AppendInittab("jucipp", init_juci_api);
Py_Initialize();
// long unsigned size = 0L;
// argv=Py_DecodeLocale("",&size);
// PySys_SetArgv(0,&argv);
Config::get().load();
add_path("/usr/lib/python3.5/site-packages");// Config::get().python.site_packages);
auto plugin_path=Config::get().juci_home_path()/"plugins"; // Config::get().python.plugin_directory;
add_path(plugin_path);
boost::filesystem::directory_iterator end_it;
for(boost::filesystem::directory_iterator it(plugin_path);it!=end_it;it++){
auto module_name=it->path().stem().string();
if(module_name!="__pycache__"){
auto module=import(module_name);
if(!module){
auto err=PythonError();
if(err)
std::cerr << std::string(err) << std::endl;
}
}
}
}

pybind11::module PythonInterpreter::get_loaded_module(const std::string &module_name){
return pybind11::module(PyImport_AddModule(module_name.c_str()), true);
}

pybind11::module PythonInterpreter::import(const std::string &module_name){
return pybind11::module(PyImport_ImportModule(module_name.c_str()), false);
}

void PythonInterpreter::add_path(const boost::filesystem::path &path){
std::wstring sys_path(Py_GetPath());
if(!sys_path.empty())
#ifdef _WIN32
sys_path += ';';
#else
sys_path += ':';
#endif
sys_path += path.generic_wstring();
Py_SetPath(sys_path.c_str());
}

PythonInterpreter::~PythonInterpreter(){
auto err=PythonError();
if(Py_IsInitialized())
Py_Finalize();
if(err)
std::cerr << std::string(err) << std::endl;
}

PythonError::PythonError(){
pybind11::object error(PyErr_Occurred(), false);
if(error){
PyObject *exception,*value,*traceback;
PyErr_Fetch(&exception,&value,&traceback);
PyErr_NormalizeException(&exception,&value,&traceback);
try{
exp=std::string(pybind11::object(exception,false).str());
val=std::string(pybind11::object(value,false).str());
trace=std::string(pybind11::object(traceback,false).str());
} catch (const std::runtime_error &e){
exp=e.what();
}
}
}

PythonError::operator std::string(){
return exp + "\n" + val + "\n" + trace;
}

PythonError::operator bool(){
return !exp.empty();
}
33 changes: 33 additions & 0 deletions src/python_interpreter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef JUCI_PYTHON_INTERPRETER_H_
#define JUCI_PYTHON_INTERPRETER_H_

#include <pybind11/pybind11.h>
#include <boost/filesystem/path.hpp>

#include <iostream>
using namespace std;

class PythonInterpreter {
private:
PythonInterpreter();
~PythonInterpreter();
wchar_t *argv;
public:
static PythonInterpreter& get(){
static PythonInterpreter singleton;
return singleton;
}
pybind11::module get_loaded_module(const std::string &module_name);
pybind11::module import(const std::string &module_name);
void add_path(const boost::filesystem::path &path);
};

class PythonError {
public:
PythonError();
operator std::string();
operator bool();
std::string exp, val, trace;
};

#endif // JUCI_PYTHON_INTERPRETER_H_

0 comments on commit d82ae2b

Please sign in to comment.