Mercurial > pub > dyncall > bindings
comparison python/pydc/pydcext.c @ 34:2682a627168c
- breaking changes:
* restrict 'Z' conversions to immutable types
* restrict 'p' to mutable types (and handles)
author | Tassilo Philipp |
---|---|
date | Sun, 12 Apr 2020 19:37:37 +0200 |
parents | ba47a3d709d7 |
children | 75fe1dec0eb4 |
comparison
equal
deleted
inserted
replaced
33:ba47a3d709d7 | 34:2682a627168c |
---|---|
323 if (!PyFloat_Check(po)) | 323 if (!PyFloat_Check(po)) |
324 return PyErr_Format( PyExc_RuntimeError, "arg %d - expeecting a float", pos ); | 324 return PyErr_Format( PyExc_RuntimeError, "arg %d - expeecting a float", pos ); |
325 dcArgDouble(gpCall, PyFloat_AsDouble(po)); | 325 dcArgDouble(gpCall, PyFloat_AsDouble(po)); |
326 break; | 326 break; |
327 | 327 |
328 case DC_SIGCHAR_POINTER: | 328 case DC_SIGCHAR_POINTER: // this will only accept integers or mutable array types (meaning only bytearray) |
329 { | |
330 DCpointer p; | |
331 if ( PyByteArray_Check(po) ) | |
332 p = (DCpointer) PyByteArray_AsString(po); // adds an extra '\0', but that's ok | |
333 #if PY_MAJOR_VERSION < 3 | |
334 else if ( PyInt_Check(po) ) | |
335 p = (DCpointer) PyInt_AS_LONG(po); | |
336 #endif | |
337 else if ( PyLong_Check(po) ) | |
338 p = (DCpointer) PyLong_AsVoidPtr(po); | |
339 else | |
340 return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a promoting pointer-type (int, bytearray)", pos ); | |
341 dcArgPointer(gpCall, p); | |
342 } | |
343 break; | |
344 | |
345 case DC_SIGCHAR_STRING: // strings are considered to be immutable objects | |
329 { | 346 { |
330 PyObject* bo = NULL; | 347 PyObject* bo = NULL; |
331 DCpointer p; | 348 const char* p; |
349 char* p_; | |
350 size_t s; | |
332 if ( PyUnicode_Check(po) ) { | 351 if ( PyUnicode_Check(po) ) { |
333 if((bo = PyUnicode_AsEncodedString(po, "utf-8", "strict"))) // !new ref! | 352 if((bo = PyUnicode_AsEncodedString(po, "utf-8", "strict"))) // !new ref! |
334 p = PyBytes_AS_STRING(bo); // Borrowed pointer | 353 p = PyBytes_AS_STRING(bo); // Borrowed pointer |
335 } else if ( DcPyString_Check(po) ) | 354 } else if ( DcPyString_Check(po) ) |
336 p = (DCpointer) DcPyString_AsString(po); | 355 p = DcPyString_AsString(po); //@@@ must not be modified in any way |
337 #if PY_MAJOR_VERSION < 3 | 356 else if ( PyByteArray_Check(po) ) |
338 else if ( PyInt_Check(po) ) | 357 p = (DCpointer) PyByteArray_AsString(po); // adds an extra '\0', but that's ok //@@@ not sure if allowed to modify |
339 p = (DCpointer) PyInt_AS_LONG(po); | |
340 #endif | |
341 else if ( PyLong_Check(po) ) | |
342 p = (DCpointer) PyLong_AsVoidPtr(po); | |
343 else | 358 else |
344 return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a promoting pointer-type (int,str)", pos ); | 359 return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a str", pos ); |
345 dcArgPointer(gpCall, p); | 360 |
361 // pointer points in any case to a buffer that shouldn't be modified, so pass a copy of the string to dyncall | |
362 s = strlen(p)+1; | |
363 p_ = malloc(s); | |
364 strncpy(p_, p, s); | |
346 Py_XDECREF(bo); | 365 Py_XDECREF(bo); |
347 } | 366 dcArgPointer(gpCall, (DCpointer)p_); |
348 break; | 367 free(p_); |
349 | |
350 case DC_SIGCHAR_STRING: | |
351 { | |
352 PyObject* bo = NULL; | |
353 const char* p; | |
354 if ( PyUnicode_Check(po) ) { | |
355 if((bo = PyUnicode_AsEncodedString(po, "utf-8", "strict"))) // !new ref! | |
356 p = PyBytes_AS_STRING(bo); // Borrowed pointer | |
357 } else if ( DcPyString_Check(po) ) { | |
358 p = DcPyString_AsString(po); | |
359 } else | |
360 return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a str", pos ); | |
361 dcArgPointer(gpCall, (DCpointer) p); | |
362 Py_XDECREF(bo); | |
363 } | 368 } |
364 break; | 369 break; |
365 | 370 |
366 default: | 371 default: |
367 return PyErr_Format( PyExc_RuntimeError, "unknown signature character '%c'", ch); | 372 return PyErr_Format( PyExc_RuntimeError, "unknown signature character '%c'", ch); |