Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into pmmaster
Browse files Browse the repository at this point in the history
  • Loading branch information
benlorenz committed Dec 4, 2023
2 parents 869e6c0 + 031cc3a commit 18f12af
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 96 deletions.
19 changes: 19 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
AlignConsecutiveDeclarations: true
AlignTrailingComments: true
AllowShortBlocksOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
BinPackArguments: true
BinPackParameters: false
BreakBeforeBraces: Stroustrup
ColumnLimit: 78
Cpp11BracedListStyle: true
IndentCaseLabels: true
IndentWidth: 4
MaxEmptyLinesToKeep: 2
PointerBindsToType: Left
SpacesBeforeTrailingComments: 4
UseTab: Never
SortIncludes: false
SpacesInAngles: true
246 changes: 151 additions & 95 deletions JuPyMake.cpp
Original file line number Diff line number Diff line change
@@ -1,132 +1,198 @@
#include <Python.h>

#include <iostream>
using std::cout;
using std::cerr;
using std::cout;
using std::endl;

#include <string>

#include <polymake/Main.h>
#include <polymake/Vector.h>

#include <csignal>

#include <thread>

/*
* Python different version stuff
*/

#if PY_MAJOR_VERSION >= 3
#define to_python_string(o) PyUnicode_FromString(o)
#else
#define to_python_string(o) PyString_FromString(const_cast<char*>(o))
#define to_python_string(o) PyString_FromString(const_cast< char* >(o))
#endif

#if PY_MAJOR_VERSION >= 3
#define char_to_python_string(o) PyUnicode_FromString(std::string(1,o).c_str())
#define char_to_python_string(o) \
PyUnicode_FromString(std::string(1, o).c_str())
#else
#define char_to_python_string(o) PyString_FromString(std::string(1,o).c_str())
#define char_to_python_string(o) \
PyString_FromString(std::string(1, o).c_str())
#endif

polymake::Main* main_polymake_session;
PyObject* JuPyMakeError;
#define SET_SIGNAL_HANDLERS \
sigset_t signal_block_set, signal_pending_set; \
sigemptyset(&signal_block_set); \
sigaddset(&signal_block_set, SIGINT); \
sigaddset(&signal_block_set, SIGALRM); \
sigprocmask(SIG_BLOCK, &signal_block_set, NULL);

#define RESET_SIGNAL_HANDLERS \
sigpending(&signal_pending_set); \
if (sigismember(&signal_pending_set, SIGINT)) { \
PyOS_sighandler_t current_handler = PyOS_setsig(SIGINT, SIG_IGN); \
sigprocmask(SIG_UNBLOCK, &signal_block_set, NULL); \
PyOS_setsig(SIGINT, current_handler); \
PyErr_SetString(PyExc_KeyboardInterrupt, "polymake interrupted"); \
PyErr_SetInterrupt(); \
PyErr_CheckSignals(); \
return NULL; \
} \
sigprocmask(SIG_UNBLOCK, &signal_block_set, NULL);


thread_local polymake::Main* main_polymake_session;
thread_local bool initialized;
bool shell_enabled;

PyObject* JuPyMakeError;

static PyObject * ToPyBool( bool input )
static PyObject* ToPyBool(bool input)
{
if(input)
if (input)
Py_RETURN_TRUE;
Py_RETURN_FALSE;
}

/*
* Python functions
*/
static PyObject * ExecuteCommand( PyObject* self, PyObject* args )
static PyObject* InitializePolymake(PyObject* self)
{
const char * input_string;
if (! PyArg_ParseTuple(args, "s", &input_string) )
if(!initialized){
SET_SIGNAL_HANDLERS
try {
main_polymake_session = new polymake::Main;
initialized = true;
if(!shell_enabled){
main_polymake_session->shell_enable();
main_polymake_session->set_application("polytope");
}
}
catch (const std::exception& e) {
RESET_SIGNAL_HANDLERS
PyErr_SetString(JuPyMakeError, e.what());
return NULL;
}
RESET_SIGNAL_HANDLERS
}
Py_RETURN_TRUE;
}

static PyObject* ExecuteCommand(PyObject* self, PyObject* args)
{
InitializePolymake(NULL);
const char* input_string;
if (!PyArg_ParseTuple(args, "s", &input_string))
return NULL;
std::string polymake_input(input_string);
bool parsed;
bool parsed;
std::string stdout;
std::string stderr;
std::string error;
try{
std::tie(parsed,stdout,stderr,error) = main_polymake_session->shell_execute(polymake_input);
}catch(const std::exception& e ){
PyErr_SetString( JuPyMakeError, e.what() );
SET_SIGNAL_HANDLERS
try {
std::tie(parsed, stdout, stderr, error) =
main_polymake_session->shell_execute(polymake_input);
}
catch (const std::exception& e) {
RESET_SIGNAL_HANDLERS
PyErr_SetString(JuPyMakeError, e.what());
return NULL;
}
return PyTuple_Pack( 4, ToPyBool( parsed ), to_python_string( stdout.c_str() ), to_python_string( stderr.c_str() ), to_python_string( error.c_str() ) );
RESET_SIGNAL_HANDLERS
return PyTuple_Pack(4, ToPyBool(parsed), to_python_string(stdout.c_str()),
to_python_string(stderr.c_str()),
to_python_string(error.c_str()));
}

static PyObject * GetCompletion( PyObject* self, PyObject* args )
static PyObject* GetCompletion(PyObject* self, PyObject* args)
{
InitializePolymake(NULL);
const char* input_string;
if (! PyArg_ParseTuple(args, "s", &input_string) )
if (!PyArg_ParseTuple(args, "s", &input_string))
return NULL;
std::string polymake_input(input_string);
std::vector<std::string> completions;
int completion_offset;
char additional_character;
try{
std::tie(completion_offset,additional_character, completions) = main_polymake_session->shell_complete(polymake_input);
}catch(const std::exception& e ){
PyErr_SetString( JuPyMakeError, e.what() );
return NULL;
std::string polymake_input(input_string);
std::vector< std::string > completions;
int completion_offset;
char additional_character;
SET_SIGNAL_HANDLERS
try {
std::tie(completion_offset, additional_character, completions) =
main_polymake_session->shell_complete(polymake_input);
}
int completions_length = completions.size();
PyObject* return_list = PyList_New( completions_length );
for(int i=0;i<completions_length;i++){
PyList_SetItem( return_list, i, to_python_string( completions[ i ].c_str() ) );
catch (const std::exception& e) {
RESET_SIGNAL_HANDLERS
PyErr_SetString(JuPyMakeError, e.what());
return NULL;
}
RESET_SIGNAL_HANDLERS
int completions_length = completions.size();
PyObject* return_list = PyList_New(completions_length);
for (int i = 0; i < completions_length; i++) {
PyList_SetItem(return_list, i,
to_python_string(completions[i].c_str()));
}
return PyTuple_Pack( 3, PyLong_FromLong( completion_offset ), char_to_python_string(additional_character), return_list );
return PyTuple_Pack(3, PyLong_FromLong(completion_offset),
char_to_python_string(additional_character),
return_list);
}

static PyObject * GetContextHelp( PyObject* self, PyObject* args, PyObject* kwargs )
static PyObject*
GetContextHelp(PyObject* self, PyObject* args, PyObject* kwargs)
{
const char* input_string;
int position = -1;
int full=false;
int html=false;
static char* kwlist[] = { "input", "position", "full", "html", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kwargs, "s|iii", kwlist, &input_string, &position, &full, &html ) )
InitializePolymake(NULL);
const char* input_string;
int position = -1;
int full = false;
int html = false;
static char* kwlist[] = {"input", "position", "full", "html", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iii", kwlist,
&input_string, &position, &full, &html))
return NULL;
std::string polymake_input(input_string);
if(position == -1){
position = static_cast<int>(std::string::npos);
if (position == -1) {
position = static_cast< int >(std::string::npos);
}
std::vector< std::string > results;
SET_SIGNAL_HANDLERS
try {
results = main_polymake_session->shell_context_help(
polymake_input, position, static_cast< bool >(full),
static_cast< bool >(html));
}
std::vector<std::string> results;
try{
results = main_polymake_session->shell_context_help(polymake_input,position,static_cast<bool>(full),static_cast<bool>(html));
}catch(const std::exception& e ){
PyErr_SetString( JuPyMakeError, e.what() );
catch (const std::exception& e) {
RESET_SIGNAL_HANDLERS
PyErr_SetString(JuPyMakeError, e.what());
return NULL;
}
int results_length = results.size();
PyObject* return_list = PyList_New( results_length );
for(int i=0;i<results_length;i++){
PyList_SetItem( return_list, i, to_python_string( results[ i ].c_str() ) );
RESET_SIGNAL_HANDLERS
int results_length = results.size();
PyObject* return_list = PyList_New(results_length);
for (int i = 0; i < results_length; i++) {
PyList_SetItem(return_list, i, to_python_string(results[i].c_str()));
}
return return_list;
}

static PyObject * InitializePolymake( PyObject* self )
{
try{
main_polymake_session = new polymake::Main;
main_polymake_session->shell_enable();
main_polymake_session->set_application("polytope");
}catch(const std::exception& e){
PyErr_SetString( JuPyMakeError, e.what() );
return NULL;
}
Py_RETURN_TRUE;
}
/*
* Python mixed init stuff
*/

struct module_state {
PyObject *error;
PyObject* error;
};

#if PY_MAJOR_VERSION >= 3
Expand All @@ -136,50 +202,39 @@ struct module_state {
static struct module_state _state;
#endif

static PyObject * error_out(PyObject *m) {
struct module_state *st = GETSTATE(m);
PyErr_SetString(st->error, "something bad happened");
return NULL;
}

static PyMethodDef JuPyMakeMethods[] = {
{"ExecuteCommand",(PyCFunction)ExecuteCommand, METH_VARARGS,
{"ExecuteCommand", (PyCFunction)ExecuteCommand, METH_VARARGS,
"Runs a polymake command"},
{"GetCompletion",(PyCFunction)GetCompletion, METH_VARARGS,
{"GetCompletion", (PyCFunction)GetCompletion, METH_VARARGS,
"Get tab completions of string"},
{"GetContextHelp",(PyCFunction)GetContextHelp,METH_VARARGS | METH_KEYWORDS,
"Get context help of string"},
{"InitializePolymake",(PyCFunction)InitializePolymake,METH_NOARGS,
"Initialize the polymake session"},
{NULL, NULL, 0, NULL} /* Sentinel */
{"GetContextHelp", (PyCFunction)GetContextHelp,
METH_VARARGS | METH_KEYWORDS, "Get context help of string"},
{"InitializePolymake", (PyCFunction)InitializePolymake, METH_NOARGS,
"Initialize the polymake session"},

{NULL, NULL, 0, NULL} /* Sentinel */
};


#if PY_MAJOR_VERSION >= 3

static int JuPyMake_traverse(PyObject *m, visitproc visit, void *arg) {
static int JuPyMake_traverse(PyObject* m, visitproc visit, void* arg)
{
Py_VISIT(GETSTATE(m)->error);
return 0;
}

static int JuPyMake_clear(PyObject *m) {
static int JuPyMake_clear(PyObject* m)
{
Py_CLEAR(GETSTATE(m)->error);
return 0;
}


static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"JuPyMake",
NULL,
sizeof(struct module_state),
JuPyMakeMethods,
NULL,
JuPyMake_traverse,
JuPyMake_clear,
NULL
};
PyModuleDef_HEAD_INIT, "JuPyMake", NULL,
sizeof(struct module_state), JuPyMakeMethods, NULL,
JuPyMake_traverse, JuPyMake_clear, NULL};

#define INITERROR return NULL

Expand All @@ -192,16 +247,17 @@ extern "C" void initJuPyMake(void)
#endif
{
#if PY_MAJOR_VERSION >= 3
PyObject *module = PyModule_Create(&moduledef);
PyObject* module = PyModule_Create(&moduledef);
#else
PyObject *module = Py_InitModule("JuPyMake", JuPyMakeMethods);
PyObject* module = Py_InitModule("JuPyMake", JuPyMakeMethods);
#endif

if (module == NULL)
INITERROR;
struct module_state *st = GETSTATE(module);
JuPyMakeError = PyErr_NewException(const_cast<char*>("JuPyMake.PolymakeError"), NULL, NULL );
Py_INCREF( JuPyMakeError );
struct module_state* st = GETSTATE(module);
JuPyMakeError = PyErr_NewException(
const_cast< char* >("JuPyMake.PolymakeError"), NULL, NULL);
Py_INCREF(JuPyMakeError);
st->error = JuPyMakeError;

#if PY_MAJOR_VERSION >= 3
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def conditional_decode( string ):
setup(
ext_modules= [ Extension( "JuPyMake",
[ "JuPyMake.cpp" ],
extra_compile_args=polymake_cflags,
extra_compile_args=polymake_cflags + [ '-pthread' ],
extra_link_args=polymake_ldflags,
define_macros = macro_list ) ],
)

0 comments on commit 18f12af

Please sign in to comment.