-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpython.c
More file actions
317 lines (268 loc) · 12.2 KB
/
Copy pathpython.c
File metadata and controls
317 lines (268 loc) · 12.2 KB
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
// Some of the source code came originaly from https://github.com/FiveTechSoft/harbour_python
// Added new functions and minor changes.
// https://docs.python.org/3/c-api/unicode.html
#include <hbapi.h>
#include <hbapiitm.h>
#include <Python.h>
HB_FUNC( PY_INITIALIZE ) // Initializes the embedded Python interpreter (cPython). Call this once before any other Python operations.
{
Py_Initialize();
}
HB_FUNC( PY_FINALIZE ) // Finalizes the Python interpreter. Call this when you're done using Python.
{
Py_Finalize();
// _M_ inhance this by using Py_FinalizeEx() -> int status code
}
HB_FUNC( PY_GETLASTERRORTEXT ) // Fetches the last Python exception and returns it as a string.
{
PyObject * type, * value, * traceback;
PyErr_Fetch( &type, &value, &traceback );
if( value )
{
void * str_exc = PyObject_Str(value);
const char * c_str_exc = PyUnicode_AsUTF8(str_exc);
hb_retc( c_str_exc );
}
}
HB_FUNC( PY_CREATEPYTHONFLOAT ) // Create a new Python Float (Object) from a Harbour numeric.
{
hb_retptr( PyFloat_FromDouble( hb_parnd( 1 ) ) );
// https://docs.python.org/3/c-api/float.html
// PyObject *PyFloat_FromDouble(double v)
// Return value: New reference. Part of the Stable ABI.
// Create a PyFloatObject object from v, or NULL on failure.
}
HB_FUNC( PY_CREATEPYTHONINTEGER ) // Create a new Python Integer (Object) from a Harbour numeric (integer).
{
int nValue = hb_parni(1);
hb_retptr( PyLong_FromLong( (long) nValue ) );
}
HB_FUNC( PY_GETPYTHONFLOATVALUE ) // Get the Harbour numeric value from a Python float object.
{
//https://docs.python.org/3/c-api/float.html
// double PyFloat_AsDouble(PyObject *pyfloat)
// Part of the Stable ABI.
// Return a C double representation of the contents of pyfloat. If pyfloat is not a Python floating point object but has a __float__() method, this method will first be called to convert pyfloat into a float. If __float__() is not defined then it falls back to __index__(). This method returns -1.0 upon failure, so one should call PyErr_Occurred() to check for errors.
// Changed in version 3.8: Use __index__() if available.
hb_retnd( PyFloat_AsDouble( hb_parptr( 1 ) ) );
}
HB_FUNC( PY_CREATEPYTHONSTRING ) // Create a new Python String (Object) from a Harbour UTF string.
{
hb_retptr( PyUnicode_FromString( hb_parc( 1 ) ) );
}
HB_FUNC( PY_GETPYTHONSTRINGVALUE )
{
//https://docs.python.org/3/c-api/unicode.html
// PyObject *PyUnicode_AsUTF8String(PyObject *unicode)
// Return value: New reference. Part of the Stable ABI.
// Encode a Unicode object using UTF-8 and return the result as Python bytes object. Error handling is “strict”. Return NULL if an exception was raised by the codec.
PyObject *pStr = ( PyObject * ) hb_parptr( 1 );
if( pStr && PyUnicode_Check( pStr ) )
{
const char *cStr = PyUnicode_AsUTF8( pStr );
hb_retc( cStr ? cStr : "" );
}
else
{
hb_retc( "" );
}
}
HB_FUNC( PY_ISPYTHONSTRING ) // Checks whether the given Python object is a string (Unicode).
{
PyObject * obj = ( PyObject * ) hb_parptr( 1 );
if( obj && PyUnicode_Check( obj ) )
hb_retl( 1 );
else
hb_retl( 0 );
}
HB_FUNC( PY_CREATEPYTHONLIST ) // Creates a new Python list of the given size.
{
hb_retptr( PyList_New( hb_parni( 1 ) ) );
}
HB_FUNC( PY_SETPYTHONLISTITEM ) // Sets an item in a Python list at the specified index.
{
PyList_SetItem( hb_parptr( 1 ), hb_parni( 2 ), hb_parptr( 3 ) );
}
HB_FUNC( PY_GETPYTHONLISTITEM ) // Returns a pointer to the item at the given nIndex in a Python list.
{
PyObject *pList = ( PyObject * ) hb_parptr( 1 );
Py_ssize_t index = ( Py_ssize_t ) hb_parnint( 2 );
if( pList && PyList_Check( pList ) )
{
hb_retptr( PyList_GetItem( pList, index ) );
}
else
{
hb_retptr( NULL );
}
}
HB_FUNC( PY_ISPYTHONLIST ) // Checks whether the given Python object is a list.
{
PyObject * obj = ( PyObject * ) hb_parptr( 1 );
if( obj && PyList_Check( obj ) )
hb_retl( 1 );
else
hb_retl( 0 );
}
HB_FUNC( PY_GETPYTHONLISTSIZE ) // Returns the number of elements in a Python list.
{
PyObject *pList = ( PyObject * ) hb_parptr( 1 );
if( pList && PyList_Check( pList ) )
{
hb_retni( ( int ) PyList_Size( pList ) );
}
else
{
hb_retni( 0 );
}
}
HB_FUNC( PY_RELEASEVARIABLEUSE ) // Release Python Variable Reference.
{
if (hb_pcount() >= 1) {
Py_XDECREF( hb_parptr( 1 ) );
if (hb_parinfo(1) & HB_IT_BYREF)
{
PHB_ITEM pItem = hb_param( 1, HB_IT_BYREF );
if( pItem )
hb_itemClear( pItem );
}
}
}
HB_FUNC( PY_IMPORTPYTHONMODULE )
{
hb_retptr( PyImport_ImportModule( hb_parc( 1 ) ) );
}
HB_FUNC( PY_GETOBJECTATTRIBUTEVALUEBYNAME )
{
hb_retptr( PyObject_GetAttrString( hb_parptr( 1 ), hb_parc( 2 ) ) );
//https://docs.python.org/3/c-api/object.html
//PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)
// Return value: New reference. Part of the Stable ABI.
// Retrieve an attribute named attr_name from object o. Returns the attribute value on success, or NULL on failure. This is the equivalent of the Python expression o.attr_name.
}
//----------------------------------------------------------------------------------------------------------------------------------------------------
HB_FUNC( PY_CALLFUNCTION ) // Calls a Python user created function with up to 12 arguments.
{
//https://docs.python.org/3/c-api/call.html#c.PyObject_CallFunctionObjArgs
// Call a callable Python object callable, with a variable number of PyObject* arguments. The arguments are provided as a variable number of parameters followed by NULL.
// Return the result of the call on success, or raise an exception and return NULL on failure.
// This is the equivalent of the Python expression: callable(arg1, arg2, ...).
switch( hb_pcount() )
{
case 1:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1), NULL ) );
break;
case 2:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1),hb_parptr(2), NULL ) );
break;
case 3:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1),hb_parptr(2),hb_parptr(3), NULL ) );
break;
case 4:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1),hb_parptr(2),hb_parptr(3),hb_parptr(4), NULL ) );
break;
case 5:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1),hb_parptr(2),hb_parptr(3),hb_parptr(4),hb_parptr(5), NULL ) );
break;
case 6:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1),hb_parptr(2),hb_parptr(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),NULL) );
break;
case 7:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1),hb_parptr(2),hb_parptr(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),NULL) );
break;
case 8:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1),hb_parptr(2),hb_parptr(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8),NULL) );
break;
case 9:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1),hb_parptr(2),hb_parptr(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8),hb_parptr(9),NULL) );
break;
case 10:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1),hb_parptr(2),hb_parptr(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8),hb_parptr(9),hb_parptr(10),NULL) );
break;
case 11:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1),hb_parptr(2),hb_parptr(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8),hb_parptr(9),hb_parptr(10),hb_parptr(11),NULL) );
break;
case 12:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1),hb_parptr(2),hb_parptr(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8),hb_parptr(9),hb_parptr(10),hb_parptr(11),hb_parptr(12),NULL) );
break;
case 13:
hb_retptr( PyObject_CallFunctionObjArgs(hb_parptr(1),hb_parptr(2),hb_parptr(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8),hb_parptr(9),hb_parptr(10),hb_parptr(11),hb_parptr(12),hb_parptr(13),NULL) );
break;
default:
// generate error reporting increase this switch
break;
}
}
HB_FUNC( PY_CALLMETHOD ) // Calls a named method of a Python object.
{
//https://docs.python.org/3/c-api/call.html#c.PyObject_CallFunctionObjArgs
// PyObject *PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...)
// Return value: New reference. Part of the Stable ABI.
// Call the method named name of object obj with a variable number of C arguments. The C arguments are described by a Py_BuildValue() format string that should produce a tuple.
// The format can be NULL, indicating that no arguments are provided.
// Return the result of the call on success, or raise an exception and return NULL on failure.
// This is the equivalent of the Python expression: obj.name(arg1, arg2, ...).
// Note that if you only pass PyObject* args, PyObject_CallMethodObjArgs() is a faster alternative.
// Changed in version 3.4: The types of name and format were changed from char *.
switch( hb_pcount() )
{
case 2:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2), NULL ) );
break;
case 3:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2),hb_parptr(3), NULL ) );
break;
case 4:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2),hb_parc(3),hb_parptr(4), NULL ) );
break;
case 5:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2),hb_parc(3),hb_parptr(4),hb_parptr(5), NULL ) );
break;
case 6:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2),hb_parc(3),hb_parptr(4),hb_parptr(5),hb_parptr(6), NULL ) );
break;
case 7:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2),hb_parc(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7), NULL ) );
break;
case 8:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2),hb_parc(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8), NULL ) );
break;
case 9:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2),hb_parc(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8),hb_parptr(9), NULL ) );
break;
case 10:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2),hb_parc(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8),hb_parptr(9),hb_parptr(10), NULL ) );
break;
case 11:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2),hb_parc(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8),hb_parptr(9),hb_parptr(10),hb_parptr(11), NULL ) );
break;
case 12:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2),hb_parc(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8),hb_parptr(9),hb_parptr(10),hb_parptr(11),hb_parptr(12), NULL ) );
break;
case 13:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2),hb_parc(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8),hb_parptr(9),hb_parptr(10),hb_parptr(11),hb_parptr(12),hb_parptr(13), NULL ) );
break;
case 14:
hb_retptr( PyObject_CallMethod(hb_parptr(1),hb_parc(2),hb_parc(3),hb_parptr(4),hb_parptr(5),hb_parptr(6),hb_parptr(7),hb_parptr(8),hb_parptr(9),hb_parptr(10),hb_parptr(11),hb_parptr(12),hb_parptr(13),hb_parptr(14), NULL ) );
break;
default:
// generate error reporting increase this switch
break;
}
}
HB_FUNC( PY_ERROROCCURRED ) // Checks if a Python error has occurred.
{
hb_retl( PyErr_Occurred() != NULL );
}
HB_FUNC( PY_PRINTLASTERROR ) // Prints the last Python error (if any) to stderr (useful for debugging).
{
PyErr_Print();
}
HB_FUNC( PY_GETTYPE ) // Get the type of a Python pointer.
{
PyObject * pObj = (PyObject *) hb_parptr( 1 );
if( pObj && Py_TYPE( pObj ) && Py_TYPE( pObj )->tp_name )
hb_retc( Py_TYPE( pObj )->tp_name );
else
hb_retc( "null" );
}