forked from jupyter-xeus/xeus-python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxutils.cpp
139 lines (118 loc) · 3.76 KB
/
xutils.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/***************************************************************************
* Copyright (c) 2018, Martin Renou, Johan Mabille, Sylvain Corlay, and *
* Wolf Vollprecht *
* Copyright (c) 2018, QuantStack *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/
#include <cmath>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
#ifdef WIN32
#include "Windows.h"
#endif
#ifdef __GNUC__
#include <stdio.h>
#ifndef XPYT_EMSCRIPTEN_WASM_BUILD
#include <execinfo.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#endif
#include "nlohmann/json.hpp"
#include "xeus/xcomm.hpp"
#include "xeus/xsystem.hpp"
#include "pybind11_json/pybind11_json.hpp"
#include "pybind11/pybind11.h"
#include "pybind11/eval.h"
#include "xeus-python/xutils.hpp"
namespace py = pybind11;
namespace nl = nlohmann;
namespace xpyt
{
bool is_pyobject_true(const py::object& obj)
{
return PyObject_IsTrue(obj.ptr());
}
bool holding_gil()
{
return PyGILState_Check();
}
void exec(const py::object& code, const py::object& scope)
{
py::exec("exec(_code_, _scope_, _scope_)", py::globals(), py::dict(py::arg("_code_") = code, py::arg("_scope_") = scope));
}
py::object eval(const py::object& code, const py::object& scope)
{
return py::eval(code, scope);
}
bool extract_option(std::string short_opt, std::string long_opt, int argc, char* argv[])
{
bool res = false;
for (int i = 0; i < argc; ++i)
{
if (((std::string(argv[i]) == short_opt) || (std::string(argv[i]) == long_opt)))
{
res = true;
for (int j = i; j < argc - 1; ++j)
{
argv[j] = argv[j + 1];
}
argc -= 1;
break;
}
}
return res;
}
void sigsegv_handler(int sig)
{
#if defined(__GNUC__) && !defined(XPYT_EMSCRIPTEN_WASM_BUILD)
void* array[10];
// get void*'s for all entries on the stack
int size = backtrace(array, 10);
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
#endif
exit(1);
}
void sigkill_handler(int /*sig*/)
{
exit(0);
}
void print_pythonhome()
{
std::setlocale(LC_ALL, "en_US.utf8");
// Py_GetPythonHome will return NULL if called before Py_Initialize()
wchar_t* ph = Py_GetPythonHome();
if (ph)
{
char mbstr[1024];
std::wcstombs(mbstr, ph, 1024);
std::clog << "PYTHONHOME set to " << mbstr << std::endl;
}
else
{
std::clog << "PYTHONHOME not set or not initialized." << std::endl;
}
}
// Compares 2 versions and return true if version1 < version2.
// The versions must be strings formatted as the regex: [0-9]+(\s[0-9]+)*
bool less_than_version(std::string version1, std::string version2)
{
using iterator_type = std::istream_iterator<int>;
std::istringstream iv1(version1), iv2(version2);
return std::lexicographical_compare(
iterator_type(iv1),
iterator_type(),
iterator_type(iv2),
iterator_type()
);
}
}