Version: 9.16.0
PyStdout.cxx
Go to the documentation of this file.
1// Copyright (C) 2006-2026 CEA, EDF
2//
3// This library is free software; you can redistribute it and/or
4// modify it under the terms of the GNU Lesser General Public
5// License as published by the Free Software Foundation; either
6// version 2.1 of the License, or (at your option) any later version.
7//
8// This library is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11// Lesser General Public License for more details.
12//
13// You should have received a copy of the GNU Lesser General Public
14// License along with this library; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16//
17// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18//
19
20#include "PyStdout.hxx"
21#include "Exception.hxx"
22#include "PythonCppUtils.hxx"
23
24#include <structmember.h>
25
26#include <string>
27#include <sstream>
28
29#ifdef WIN32
30#include <process.h>
31#define getpid _getpid
32#endif
33
34namespace YACS
35{
36 namespace ENGINE
37 {
38
39 typedef struct {
40 PyObject_HEAD
42 std::string *out;
43 } PyStdOut;
44
45static void
47{
48 PyObject_Del(self);
49}
50
51static PyObject *
52PyStdOut_write(PyStdOut *self, PyObject *args)
53{
54 char *c;
56 if (!PyArg_ParseTuple(args, "s#:write",&c, &l))
57 return NULL;
58
59 //std::cerr << c ;
60 *(self->out)=*(self->out)+std::string(c);
61
62 Py_INCREF(Py_None);
63 return Py_None;
64}
65
66static PyMethodDef PyStdOut_methods[] = {
67 {"write", (PyCFunction)PyStdOut_write, METH_VARARGS,
68 PyDoc_STR("write(string) -> None")},
69 {NULL, NULL} /* sentinel */
70};
71
72static PyMemberDef PyStdOut_memberlist[] = {
73 {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
74 (char*)"flag indicating that a space needs to be printed; used by print"},
75 {NULL} /* Sentinel */
76};
77
78static PyTypeObject PyStdOut_Type = {
79 /* The ob_type field must be initialized in the module init function
80 * to be portable to Windows without using C++. */
81 PyVarObject_HEAD_INIT(NULL, 0)
82 /*0,*/ /*ob_size*/
83 "PyOut", /*tp_name*/
84 sizeof(PyStdOut), /*tp_basicsize*/
85 0, /*tp_itemsize*/
86 /* methods */
87 (destructor)PyStdOut_dealloc, /*tp_dealloc*/
88 0, /*tp_print*/
89 0, /*tp_getattr*/
90 0, /*tp_setattr*/
91 0, /*tp_compare*/
92 0, /*tp_repr*/
93 0, /*tp_as_number*/
94 0, /*tp_as_sequence*/
95 0, /*tp_as_mapping*/
96 0, /*tp_hash*/
97 0, /*tp_call*/
98 0, /*tp_str*/
99 PyObject_GenericGetAttr, /*tp_getattro*/
100 /* softspace is writable: we must supply tp_setattro */
101 PyObject_GenericSetAttr, /* tp_setattro */
102 0, /*tp_as_buffer*/
103 Py_TPFLAGS_DEFAULT, /*tp_flags*/
104 0, /*tp_doc*/
105 0, /*tp_traverse*/
106 0, /*tp_clear*/
107 0, /*tp_richcompare*/
108 0, /*tp_weaklistoffset*/
109 0, /*tp_iter*/
110 0, /*tp_iternext*/
111 PyStdOut_methods, /*tp_methods*/
112 PyStdOut_memberlist, /*tp_members*/
113 0, /*tp_getset*/
114 0, /*tp_base*/
115 0, /*tp_dict*/
116 0, /*tp_descr_get*/
117 0, /*tp_descr_set*/
118 0, /*tp_dictoffset*/
119 0, /*tp_init*/
120 0, /*tp_alloc*/
121 0, /*tp_new*/
122 0, /*tp_free*/
123 0, /*tp_is_gc*/
124};
125
126
127#define PyStdOut_Check(v) ((v)->ob_type == &PyStdOut_Type)
128
129PyObject * newPyStdOut( std::string& out )
130{
131 PyStdOut *self;
132 self = PyObject_New(PyStdOut, &PyStdOut_Type);
133 if (self == NULL)
134 return NULL;
135 self->softspace = 0;
136 self->out=&out;
137 return (PyObject*)self;
138}
139
140PyObject *evalPy(const std::string& funcName, const std::string& strToEval)
141{
142 std::ostringstream oss0; oss0 << "def " << funcName << "():\n";
143 std::string::size_type i0(0);
144 while(i0<strToEval.length() && i0!=std::string::npos)
145 {
146 std::string::size_type i2(strToEval.find('\n',i0));
147 std::string::size_type lgth(i2!=std::string::npos?i2-i0:std::string::npos);
148 std::string part(strToEval.substr(i0,lgth));
149 if(!part.empty())
150 oss0 << " " << part << "\n";
151 i0=i2!=std::string::npos?i2+1:std::string::npos;
152 }
153 std::string zeCodeStr(oss0.str());
154 AutoPyRef context(PyDict_New());
155 PyDict_SetItemString( context, "__builtins__", PyEval_GetBuiltins() );
156 AutoPyRef code(Py_CompileString(zeCodeStr.c_str(), "kkkk", Py_file_input));
157 if(code.isNull())
158 {
159 std::string errorDetails;
160 PyObject *new_stderr(newPyStdOut(errorDetails));
161 PySys_SetObject((char*)"stderr", new_stderr);
162 PyErr_Print();
163 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
164 Py_DECREF(new_stderr);
165 std::ostringstream oss; oss << "evalPy failed : " << errorDetails;
166 throw Exception(oss.str());
167 }
168 AutoPyRef res(PyEval_EvalCode((PyObject *)code,context,context));
169 PyObject *ret(PyDict_GetItemString(context,funcName.c_str())); //borrowed ref
170 if(!ret)
171 throw YACS::Exception("evalPy : Error on returned func !");
172 Py_XINCREF(ret);
173 return ret;
174}
175
176PyObject *evalFuncPyWithNoParams(PyObject *func)
177{
178 if(!func)
179 throw YACS::Exception("evalFuncPyWithNoParams : input func is NULL !");
180 AutoPyRef args(PyTuple_New(0));
181 AutoPyRef ret(PyObject_CallObject(func,args));
182 if(ret.isNull())
183 throw YACS::Exception("evalFuncPyWithNoParams : ret is null !");
184 return ret.retn();
185}
186
187}
188}
189
int Py_ssize_t
Definition: PythonNode.cxx:45
static void PyStdOut_dealloc(PyStdOut *self)
Definition: PyStdout.cxx:46
PyObject * evalFuncPyWithNoParams(PyObject *func)
Definition: PyStdout.cxx:176
PyObject * evalPy(const std::string &funcName, const std::string &strToEval)
Definition: PyStdout.cxx:140
PyObject * newPyStdOut(std::string &out)
Definition: PyStdout.cxx:129
static PyTypeObject PyStdOut_Type
Definition: PyStdout.cxx:78
static PyObject * PyStdOut_write(PyStdOut *self, PyObject *args)
Definition: PyStdout.cxx:52
static PyMethodDef PyStdOut_methods[]
Definition: PyStdout.cxx:66
static PyMemberDef PyStdOut_memberlist[]
Definition: PyStdout.cxx:72
std::string * out
Definition: PyStdout.cxx:42
PyObject_HEAD int softspace
Definition: PyStdout.cxx:41