1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 /** \file
18  * \ingroup pygen
19  *
20  * Extend upon CPython's API, filling in some gaps, these functions use PyC_
21  * prefix to distinguish them apart from CPython.
22  *
23  * \note
24  * This module should only depend on CPython, however it currently uses
25  * BLI_string_utf8() for unicode conversion.
26  */
27 
28 /* Future-proof, See https://docs.python.org/3/c-api/arg.html#strings-and-buffers */
29 #define PY_SSIZE_T_CLEAN
30 
31 #include <Python.h>
32 #include <frameobject.h>
33 
34 #include "BLI_utildefines.h" /* for bool */
35 
36 #include "py_capi_utils.h"
37 
38 #include "python_utildefines.h"
39 
40 #ifndef MATH_STANDALONE
41 #  include "MEM_guardedalloc.h"
42 
43 #  include "BLI_string.h"
44 
45 /* Only for BLI_strncpy_wchar_from_utf8,
46  * should replace with py funcs but too late in release now. */
47 #  include "BLI_string_utf8.h"
48 #endif
49 
50 #ifdef _WIN32
51 #  include "BLI_math_base.h" /* isfinite() */
52 #endif
53 
54 /* -------------------------------------------------------------------- */
55 /** \name Fast Python to C Array Conversion for Primitive Types
56  * \{ */
57 
58 /* array utility function */
PyC_AsArray_FAST(void * array,PyObject * value_fast,const Py_ssize_t length,const PyTypeObject * type,const bool is_double,const char * error_prefix)59 int PyC_AsArray_FAST(void *array,
60                      PyObject *value_fast,
61                      const Py_ssize_t length,
62                      const PyTypeObject *type,
63                      const bool is_double,
64                      const char *error_prefix)
65 {
66   const Py_ssize_t value_len = PySequence_Fast_GET_SIZE(value_fast);
67   PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
68   Py_ssize_t i;
69 
70   BLI_assert(PyList_Check(value_fast) || PyTuple_Check(value_fast));
71 
72   if (value_len != length) {
73     PyErr_Format(PyExc_TypeError,
74                  "%.200s: invalid sequence length. expected %d, got %d",
75                  error_prefix,
76                  length,
77                  value_len);
78     return -1;
79   }
80 
81   /* for each type */
82   if (type == &PyFloat_Type) {
83     if (is_double) {
84       double *array_double = array;
85       for (i = 0; i < length; i++) {
86         array_double[i] = PyFloat_AsDouble(value_fast_items[i]);
87       }
88     }
89     else {
90       float *array_float = array;
91       for (i = 0; i < length; i++) {
92         array_float[i] = PyFloat_AsDouble(value_fast_items[i]);
93       }
94     }
95   }
96   else if (type == &PyLong_Type) {
97     /* could use is_double for 'long int' but no use now */
98     int *array_int = array;
99     for (i = 0; i < length; i++) {
100       array_int[i] = PyC_Long_AsI32(value_fast_items[i]);
101     }
102   }
103   else if (type == &PyBool_Type) {
104     bool *array_bool = array;
105     for (i = 0; i < length; i++) {
106       array_bool[i] = (PyLong_AsLong(value_fast_items[i]) != 0);
107     }
108   }
109   else {
110     PyErr_Format(PyExc_TypeError, "%s: internal error %s is invalid", error_prefix, type->tp_name);
111     return -1;
112   }
113 
114   if (PyErr_Occurred()) {
115     PyErr_Format(PyExc_TypeError,
116                  "%s: one or more items could not be used as a %s",
117                  error_prefix,
118                  type->tp_name);
119     return -1;
120   }
121 
122   return 0;
123 }
124 
PyC_AsArray(void * array,PyObject * value,const Py_ssize_t length,const PyTypeObject * type,const bool is_double,const char * error_prefix)125 int PyC_AsArray(void *array,
126                 PyObject *value,
127                 const Py_ssize_t length,
128                 const PyTypeObject *type,
129                 const bool is_double,
130                 const char *error_prefix)
131 {
132   PyObject *value_fast;
133   int ret;
134 
135   if (!(value_fast = PySequence_Fast(value, error_prefix))) {
136     return -1;
137   }
138 
139   ret = PyC_AsArray_FAST(array, value_fast, length, type, is_double, error_prefix);
140   Py_DECREF(value_fast);
141   return ret;
142 }
143 
144 /** \} */
145 
146 /* -------------------------------------------------------------------- */
147 /** \name Typed Tuple Packing
148  *
149  * \note See #PyC_Tuple_Pack_* macros that take multiple arguments.
150  * \{ */
151 
152 /* array utility function */
PyC_Tuple_PackArray_F32(const float * array,uint len)153 PyObject *PyC_Tuple_PackArray_F32(const float *array, uint len)
154 {
155   PyObject *tuple = PyTuple_New(len);
156   for (uint i = 0; i < len; i++) {
157     PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array[i]));
158   }
159   return tuple;
160 }
161 
PyC_Tuple_PackArray_F64(const double * array,uint len)162 PyObject *PyC_Tuple_PackArray_F64(const double *array, uint len)
163 {
164   PyObject *tuple = PyTuple_New(len);
165   for (uint i = 0; i < len; i++) {
166     PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array[i]));
167   }
168   return tuple;
169 }
170 
PyC_Tuple_PackArray_I32(const int * array,uint len)171 PyObject *PyC_Tuple_PackArray_I32(const int *array, uint len)
172 {
173   PyObject *tuple = PyTuple_New(len);
174   for (uint i = 0; i < len; i++) {
175     PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(array[i]));
176   }
177   return tuple;
178 }
179 
PyC_Tuple_PackArray_I32FromBool(const int * array,uint len)180 PyObject *PyC_Tuple_PackArray_I32FromBool(const int *array, uint len)
181 {
182   PyObject *tuple = PyTuple_New(len);
183   for (uint i = 0; i < len; i++) {
184     PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array[i]));
185   }
186   return tuple;
187 }
188 
PyC_Tuple_PackArray_Bool(const bool * array,uint len)189 PyObject *PyC_Tuple_PackArray_Bool(const bool *array, uint len)
190 {
191   PyObject *tuple = PyTuple_New(len);
192   for (uint i = 0; i < len; i++) {
193     PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array[i]));
194   }
195   return tuple;
196 }
197 
198 /** \} */
199 
200 /* -------------------------------------------------------------------- */
201 /** \name Tuple/List Filling
202  * \{ */
203 
204 /**
205  * Caller needs to ensure tuple is uninitialized.
206  * Handy for filling a tuple with None for eg.
207  */
PyC_Tuple_Fill(PyObject * tuple,PyObject * value)208 void PyC_Tuple_Fill(PyObject *tuple, PyObject *value)
209 {
210   const uint tot = PyTuple_GET_SIZE(tuple);
211   uint i;
212 
213   for (i = 0; i < tot; i++) {
214     PyTuple_SET_ITEM(tuple, i, value);
215     Py_INCREF(value);
216   }
217 }
218 
PyC_List_Fill(PyObject * list,PyObject * value)219 void PyC_List_Fill(PyObject *list, PyObject *value)
220 {
221   const uint tot = PyList_GET_SIZE(list);
222   uint i;
223 
224   for (i = 0; i < tot; i++) {
225     PyList_SET_ITEM(list, i, value);
226     Py_INCREF(value);
227   }
228 }
229 
230 /** \} */
231 
232 /* -------------------------------------------------------------------- */
233 /** \name Bool/Enum Argument Parsing
234  * \{ */
235 
236 /**
237  * Use with PyArg_ParseTuple's "O&" formatting.
238  *
239  * \see #PyC_Long_AsBool for a similar function to use outside of argument parsing.
240  */
PyC_ParseBool(PyObject * o,void * p)241 int PyC_ParseBool(PyObject *o, void *p)
242 {
243   bool *bool_p = p;
244   long value;
245   if (((value = PyLong_AsLong(o)) == -1) || !ELEM(value, 0, 1)) {
246     PyErr_Format(PyExc_ValueError, "expected a bool or int (0/1), got %s", Py_TYPE(o)->tp_name);
247     return 0;
248   }
249 
250   *bool_p = value ? true : false;
251   return 1;
252 }
253 
254 /**
255  * Use with PyArg_ParseTuple's "O&" formatting.
256  */
PyC_ParseStringEnum(PyObject * o,void * p)257 int PyC_ParseStringEnum(PyObject *o, void *p)
258 {
259   struct PyC_StringEnum *e = p;
260   const char *value = _PyUnicode_AsString(o);
261   if (value == NULL) {
262     PyErr_Format(PyExc_ValueError, "expected a string, got %s", Py_TYPE(o)->tp_name);
263     return 0;
264   }
265   int i;
266   for (i = 0; e->items[i].id; i++) {
267     if (STREQ(e->items[i].id, value)) {
268       e->value_found = e->items[i].value;
269       return 1;
270     }
271   }
272 
273   /* Set as a precaution. */
274   e->value_found = -1;
275 
276   PyObject *enum_items = PyTuple_New(i);
277   for (i = 0; e->items[i].id; i++) {
278     PyTuple_SET_ITEM(enum_items, i, PyUnicode_FromString(e->items[i].id));
279   }
280   PyErr_Format(PyExc_ValueError, "expected a string in %S, got '%s'", enum_items, value);
281   Py_DECREF(enum_items);
282   return 0;
283 }
284 
285 /* silly function, we dont use arg. just check its compatible with __deepcopy__ */
PyC_CheckArgs_DeepCopy(PyObject * args)286 int PyC_CheckArgs_DeepCopy(PyObject *args)
287 {
288   PyObject *dummy_pydict;
289   return PyArg_ParseTuple(args, "|O!:__deepcopy__", &PyDict_Type, &dummy_pydict) != 0;
290 }
291 
292 /** \} */
293 
294 #ifndef MATH_STANDALONE
295 
296 /* -------------------------------------------------------------------- */
297 /** \name Simple Printing (for debugging)
298  *
299  * These are useful to run directly from a debugger to be able to inspect the state.
300  * \{ */
301 
302 /* for debugging */
PyC_ObSpit(const char * name,PyObject * var)303 void PyC_ObSpit(const char *name, PyObject *var)
304 {
305   const char *null_str = "<null>";
306   fprintf(stderr, "<%s> : ", name);
307   if (var == NULL) {
308     fprintf(stderr, "%s\n", null_str);
309   }
310   else {
311     PyObject_Print(var, stderr, 0);
312     const PyTypeObject *type = Py_TYPE(var);
313     fprintf(stderr,
314             " ref:%d, ptr:%p, type: %s\n",
315             (int)var->ob_refcnt,
316             (void *)var,
317             type ? type->tp_name : null_str);
318   }
319 }
320 
321 /**
322  * A version of #PyC_ObSpit that writes into a string (and doesn't take a name argument).
323  * Use for logging.
324  */
PyC_ObSpitStr(char * result,size_t result_len,PyObject * var)325 void PyC_ObSpitStr(char *result, size_t result_len, PyObject *var)
326 {
327   /* No name, creator of string can manage that. */
328   const char *null_str = "<null>";
329   if (var == NULL) {
330     BLI_snprintf(result, result_len, "%s", null_str);
331   }
332   else {
333     const PyTypeObject *type = Py_TYPE(var);
334     PyObject *var_str = PyObject_Repr(var);
335     if (var_str == NULL) {
336       /* We could print error here,
337        * but this may be used for generating errors - so don't for now. */
338       PyErr_Clear();
339     }
340     BLI_snprintf(result,
341                  result_len,
342                  " ref=%d, ptr=%p, type=%s, value=%.200s",
343                  (int)var->ob_refcnt,
344                  (void *)var,
345                  type ? type->tp_name : null_str,
346                  var_str ? _PyUnicode_AsString(var_str) : "<error>");
347     if (var_str != NULL) {
348       Py_DECREF(var_str);
349     }
350   }
351 }
352 
PyC_LineSpit(void)353 void PyC_LineSpit(void)
354 {
355 
356   const char *filename;
357   int lineno;
358 
359   /* Note, allow calling from outside python (RNA) */
360   if (!PyC_IsInterpreterActive()) {
361     fprintf(stderr, "python line lookup failed, interpreter inactive\n");
362     return;
363   }
364 
365   PyErr_Clear();
366   PyC_FileAndNum(&filename, &lineno);
367 
368   fprintf(stderr, "%s:%d\n", filename, lineno);
369 }
370 
PyC_StackSpit(void)371 void PyC_StackSpit(void)
372 {
373   /* Note, allow calling from outside python (RNA) */
374   if (!PyC_IsInterpreterActive()) {
375     fprintf(stderr, "python line lookup failed, interpreter inactive\n");
376     return;
377   }
378 
379   /* lame but handy */
380   const PyGILState_STATE gilstate = PyGILState_Ensure();
381   PyRun_SimpleString("__import__('traceback').print_stack()");
382   PyGILState_Release(gilstate);
383 }
384 
385 /** \} */
386 
387 /* -------------------------------------------------------------------- */
388 /** \name Access Current Frame File Name & Line Number
389  * \{ */
390 
PyC_FileAndNum(const char ** r_filename,int * r_lineno)391 void PyC_FileAndNum(const char **r_filename, int *r_lineno)
392 {
393   PyFrameObject *frame;
394 
395   if (r_filename) {
396     *r_filename = NULL;
397   }
398   if (r_lineno) {
399     *r_lineno = -1;
400   }
401 
402   if (!(frame = PyThreadState_GET()->frame)) {
403     return;
404   }
405 
406   /* when executing a script */
407   if (r_filename) {
408     *r_filename = _PyUnicode_AsString(frame->f_code->co_filename);
409   }
410 
411   /* when executing a module */
412   if (r_filename && *r_filename == NULL) {
413     /* try an alternative method to get the r_filename - module based
414      * references below are all borrowed (double checked) */
415     PyObject *mod_name = PyDict_GetItemString(PyEval_GetGlobals(), "__name__");
416     if (mod_name) {
417       PyObject *mod = PyDict_GetItem(PyImport_GetModuleDict(), mod_name);
418       if (mod) {
419         PyObject *mod_file = PyModule_GetFilenameObject(mod);
420         if (mod_file) {
421           *r_filename = _PyUnicode_AsString(mod_name);
422           Py_DECREF(mod_file);
423         }
424         else {
425           PyErr_Clear();
426         }
427       }
428 
429       /* unlikely, fallback */
430       if (*r_filename == NULL) {
431         *r_filename = _PyUnicode_AsString(mod_name);
432       }
433     }
434   }
435 
436   if (r_lineno) {
437     *r_lineno = PyFrame_GetLineNumber(frame);
438   }
439 }
440 
PyC_FileAndNum_Safe(const char ** r_filename,int * r_lineno)441 void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno)
442 {
443   if (!PyC_IsInterpreterActive()) {
444     return;
445   }
446 
447   PyC_FileAndNum(r_filename, r_lineno);
448 }
449 
450 /** \} */
451 
452 /* -------------------------------------------------------------------- */
453 /** \name Object Access Utilities
454  * \{ */
455 
456 /* Would be nice if python had this built in */
PyC_Object_GetAttrStringArgs(PyObject * o,Py_ssize_t n,...)457 PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
458 {
459   Py_ssize_t i;
460   PyObject *item = o;
461   const char *attr;
462 
463   va_list vargs;
464 
465   va_start(vargs, n);
466   for (i = 0; i < n; i++) {
467     attr = va_arg(vargs, char *);
468     item = PyObject_GetAttrString(item, attr);
469 
470     if (item) {
471       Py_DECREF(item);
472     }
473     else {
474       /* python will set the error value here */
475       break;
476     }
477   }
478   va_end(vargs);
479 
480   Py_XINCREF(item); /* final value has is increfed, to match PyObject_GetAttrString */
481   return item;
482 }
483 
484 /** \} */
485 
486 /* -------------------------------------------------------------------- */
487 /** \name Frozen Set Creation
488  * \{ */
489 
PyC_FrozenSetFromStrings(const char ** strings)490 PyObject *PyC_FrozenSetFromStrings(const char **strings)
491 {
492   const char **str;
493   PyObject *ret;
494 
495   ret = PyFrozenSet_New(NULL);
496 
497   for (str = strings; *str; str++) {
498     PyObject *py_str = PyUnicode_FromString(*str);
499     PySet_Add(ret, py_str);
500     Py_DECREF(py_str);
501   }
502 
503   return ret;
504 }
505 
506 /** \} */
507 
508 /* -------------------------------------------------------------------- */
509 /** \name Exception Utilities
510  * \{ */
511 
512 /**
513  * Similar to #PyErr_Format(),
514  *
515  * Implementation - we cant actually prepend the existing exception,
516  * because it could have _any_ arguments given to it, so instead we get its
517  * ``__str__`` output and raise our own exception including it.
518  */
PyC_Err_Format_Prefix(PyObject * exception_type_prefix,const char * format,...)519 PyObject *PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...)
520 {
521   PyObject *error_value_prefix;
522   va_list args;
523 
524   va_start(args, format);
525   error_value_prefix = PyUnicode_FromFormatV(format, args); /* can fail and be NULL */
526   va_end(args);
527 
528   if (PyErr_Occurred()) {
529     PyObject *error_type, *error_value, *error_traceback;
530     PyErr_Fetch(&error_type, &error_value, &error_traceback);
531 
532     if (PyUnicode_Check(error_value)) {
533       PyErr_Format(exception_type_prefix, "%S, %S", error_value_prefix, error_value);
534     }
535     else {
536       PyErr_Format(exception_type_prefix,
537                    "%S, %.200s(%S)",
538                    error_value_prefix,
539                    Py_TYPE(error_value)->tp_name,
540                    error_value);
541     }
542   }
543   else {
544     PyErr_SetObject(exception_type_prefix, error_value_prefix);
545   }
546 
547   Py_XDECREF(error_value_prefix);
548 
549   /* dumb to always return NULL but matches PyErr_Format */
550   return NULL;
551 }
552 
PyC_Err_SetString_Prefix(PyObject * exception_type_prefix,const char * str)553 PyObject *PyC_Err_SetString_Prefix(PyObject *exception_type_prefix, const char *str)
554 {
555   return PyC_Err_Format_Prefix(exception_type_prefix, "%s", str);
556 }
557 
558 /**
559  * Use for Python callbacks run directly from C,
560  * when we can't use normal methods of raising exceptions.
561  */
PyC_Err_PrintWithFunc(PyObject * py_func)562 void PyC_Err_PrintWithFunc(PyObject *py_func)
563 {
564   /* since we return to C code we can't leave the error */
565   PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
566   PyErr_Print();
567   PyErr_Clear();
568 
569   /* use py style error */
570   fprintf(stderr,
571           "File \"%s\", line %d, in %s\n",
572           _PyUnicode_AsString(f_code->co_filename),
573           f_code->co_firstlineno,
574           _PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name));
575 }
576 
577 /** \} */
578 
579 /* -------------------------------------------------------------------- */
580 /** \name Exception Buffer Access
581  * \{ */
582 
583 /* returns the exception string as a new PyUnicode object, depends on external traceback module */
584 #  if 0
585 
586 /* this version uses traceback module but somehow fails on UI errors */
587 
588 PyObject *PyC_ExceptionBuffer(void)
589 {
590   PyObject *traceback_mod = NULL;
591   PyObject *format_tb_func = NULL;
592   PyObject *ret = NULL;
593 
594   if (!(traceback_mod = PyImport_ImportModule("traceback"))) {
595     goto error_cleanup;
596   }
597   else if (!(format_tb_func = PyObject_GetAttrString(traceback_mod, "format_exc"))) {
598     goto error_cleanup;
599   }
600 
601   ret = PyObject_CallObject(format_tb_func, NULL);
602 
603   if (ret == Py_None) {
604     Py_DECREF(ret);
605     ret = NULL;
606   }
607 
608 error_cleanup:
609   /* could not import the module so print the error and close */
610   Py_XDECREF(traceback_mod);
611   Py_XDECREF(format_tb_func);
612 
613   return ret;
614 }
615 #  else /* verbose, non-threadsafe version */
PyC_ExceptionBuffer(void)616 PyObject *PyC_ExceptionBuffer(void)
617 {
618   PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */
619   PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */
620   PyObject *string_io = NULL;
621   PyObject *string_io_buf = NULL;
622   PyObject *string_io_mod = NULL;
623   PyObject *string_io_getvalue = NULL;
624 
625   PyObject *error_type, *error_value, *error_traceback;
626 
627   if (!PyErr_Occurred()) {
628     return NULL;
629   }
630 
631   PyErr_Fetch(&error_type, &error_value, &error_traceback);
632 
633   PyErr_Clear();
634 
635   /* import io
636    * string_io = io.StringIO()
637    */
638 
639   if (!(string_io_mod = PyImport_ImportModule("io"))) {
640     goto error_cleanup;
641   }
642   else if (!(string_io = PyObject_CallMethod(string_io_mod, "StringIO", NULL))) {
643     goto error_cleanup;
644   }
645   else if (!(string_io_getvalue = PyObject_GetAttrString(string_io, "getvalue"))) {
646     goto error_cleanup;
647   }
648 
649   /* Since these were borrowed we don't want them freed when replaced. */
650   Py_INCREF(stdout_backup);
651   Py_INCREF(stderr_backup);
652 
653   /* Both of these are freed when restoring. */
654   PySys_SetObject("stdout", string_io);
655   PySys_SetObject("stderr", string_io);
656 
657   PyErr_Restore(error_type, error_value, error_traceback);
658   PyErr_Print(); /* print the error */
659   PyErr_Clear();
660 
661   string_io_buf = PyObject_CallObject(string_io_getvalue, NULL);
662 
663   PySys_SetObject("stdout", stdout_backup);
664   PySys_SetObject("stderr", stderr_backup);
665 
666   Py_DECREF(stdout_backup); /* now sys owns the ref again */
667   Py_DECREF(stderr_backup);
668 
669   Py_DECREF(string_io_mod);
670   Py_DECREF(string_io_getvalue);
671   Py_DECREF(string_io); /* free the original reference */
672 
673   PyErr_Clear();
674   return string_io_buf;
675 
676 error_cleanup:
677   /* could not import the module so print the error and close */
678   Py_XDECREF(string_io_mod);
679   Py_XDECREF(string_io);
680 
681   PyErr_Restore(error_type, error_value, error_traceback);
682   PyErr_Print(); /* print the error */
683   PyErr_Clear();
684 
685   return NULL;
686 }
687 #  endif
688 
PyC_ExceptionBuffer_Simple(void)689 PyObject *PyC_ExceptionBuffer_Simple(void)
690 {
691   PyObject *string_io_buf = NULL;
692 
693   PyObject *error_type, *error_value, *error_traceback;
694 
695   if (!PyErr_Occurred()) {
696     return NULL;
697   }
698 
699   PyErr_Fetch(&error_type, &error_value, &error_traceback);
700 
701   if (error_value == NULL) {
702     return NULL;
703   }
704 
705   if (PyErr_GivenExceptionMatches(error_type, PyExc_SyntaxError)) {
706     /* Special exception for syntax errors,
707      * in these cases the full error is verbose and not very useful,
708      * just use the initial text so we know what the error is. */
709     if (PyTuple_CheckExact(error_value) && PyTuple_GET_SIZE(error_value) >= 1) {
710       string_io_buf = PyObject_Str(PyTuple_GET_ITEM(error_value, 0));
711     }
712   }
713 
714   if (string_io_buf == NULL) {
715     string_io_buf = PyObject_Str(error_value);
716   }
717 
718   /* Python does this too */
719   if (UNLIKELY(string_io_buf == NULL)) {
720     string_io_buf = PyUnicode_FromFormat("<unprintable %s object>", Py_TYPE(error_value)->tp_name);
721   }
722 
723   PyErr_Restore(error_type, error_value, error_traceback);
724 
725   PyErr_Print();
726   PyErr_Clear();
727   return string_io_buf;
728 }
729 
730 /** \} */
731 
732 /* -------------------------------------------------------------------- */
733 /** \name Unicode Conversion
734  *
735  * In some cases we need to coerce strings, avoid doing this inline.
736  * \{ */
737 
738 /* string conversion, escape non-unicode chars, coerce must be set to NULL */
PyC_UnicodeAsByteAndSize(PyObject * py_str,Py_ssize_t * size,PyObject ** coerce)739 const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObject **coerce)
740 {
741   const char *result;
742 
743   result = _PyUnicode_AsStringAndSize(py_str, size);
744 
745   if (result) {
746     /* 99% of the time this is enough but we better support non unicode
747      * chars since blender doesn't limit this */
748     return result;
749   }
750 
751   PyErr_Clear();
752 
753   if (PyBytes_Check(py_str)) {
754     *size = PyBytes_GET_SIZE(py_str);
755     return PyBytes_AS_STRING(py_str);
756   }
757   if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
758     *size = PyBytes_GET_SIZE(*coerce);
759     return PyBytes_AS_STRING(*coerce);
760   }
761 
762   /* leave error raised from EncodeFS */
763   return NULL;
764 }
765 
PyC_UnicodeAsByte(PyObject * py_str,PyObject ** coerce)766 const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
767 {
768   const char *result;
769 
770   result = _PyUnicode_AsString(py_str);
771 
772   if (result) {
773     /* 99% of the time this is enough but we better support non unicode
774      * chars since blender doesn't limit this. */
775     return result;
776   }
777 
778   PyErr_Clear();
779 
780   if (PyBytes_Check(py_str)) {
781     return PyBytes_AS_STRING(py_str);
782   }
783   if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
784     return PyBytes_AS_STRING(*coerce);
785   }
786 
787   /* leave error raised from EncodeFS */
788   return NULL;
789 }
790 
PyC_UnicodeFromByteAndSize(const char * str,Py_ssize_t size)791 PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size)
792 {
793   PyObject *result = PyUnicode_FromStringAndSize(str, size);
794   if (result) {
795     /* 99% of the time this is enough but we better support non unicode
796      * chars since blender doesn't limit this */
797     return result;
798   }
799 
800   PyErr_Clear();
801   /* this means paths will always be accessible once converted, on all OS's */
802   result = PyUnicode_DecodeFSDefaultAndSize(str, size);
803   return result;
804 }
805 
PyC_UnicodeFromByte(const char * str)806 PyObject *PyC_UnicodeFromByte(const char *str)
807 {
808   return PyC_UnicodeFromByteAndSize(str, strlen(str));
809 }
810 
811 /** \} */
812 
813 /* -------------------------------------------------------------------- */
814 /** \name Name Space Creation/Manipulation
815  * \{ */
816 
817 /*****************************************************************************
818  * Description: This function creates a new Python dictionary object.
819  * note: dict is owned by sys.modules["__main__"] module, reference is borrowed
820  * note: important we use the dict from __main__, this is what python expects
821  * for 'pickle' to work as well as strings like this...
822  * >> foo = 10
823  * >> print(__import__("__main__").foo)
824  *
825  * note: this overwrites __main__ which gives problems with nested calls.
826  * be sure to run PyC_MainModule_Backup & PyC_MainModule_Restore if there is
827  * any chance that python is in the call stack.
828  ****************************************************************************/
PyC_DefaultNameSpace(const char * filename)829 PyObject *PyC_DefaultNameSpace(const char *filename)
830 {
831   PyObject *modules = PyImport_GetModuleDict();
832   PyObject *builtins = PyEval_GetBuiltins();
833   PyObject *mod_main = PyModule_New("__main__");
834   PyDict_SetItemString(modules, "__main__", mod_main);
835   Py_DECREF(mod_main); /* sys.modules owns now */
836   PyModule_AddStringConstant(mod_main, "__name__", "__main__");
837   if (filename) {
838     /* __file__ mainly for nice UI'ness
839      * note: this wont map to a real file when executing text-blocks and buttons. */
840     PyModule_AddObject(mod_main, "__file__", PyC_UnicodeFromByte(filename));
841   }
842   PyModule_AddObject(mod_main, "__builtins__", builtins);
843   Py_INCREF(builtins); /* AddObject steals a reference */
844   return PyModule_GetDict(mod_main);
845 }
846 
PyC_NameSpace_ImportArray(PyObject * py_dict,const char * imports[])847 bool PyC_NameSpace_ImportArray(PyObject *py_dict, const char *imports[])
848 {
849   for (int i = 0; imports[i]; i++) {
850     PyObject *name = PyUnicode_FromString(imports[i]);
851     PyObject *mod = PyImport_ImportModuleLevelObject(name, NULL, NULL, 0, 0);
852     bool ok = false;
853     if (mod) {
854       PyDict_SetItem(py_dict, name, mod);
855       ok = true;
856       Py_DECREF(mod);
857     }
858     Py_DECREF(name);
859 
860     if (!ok) {
861       return false;
862     }
863   }
864   return true;
865 }
866 
867 /* restore MUST be called after this */
PyC_MainModule_Backup(PyObject ** main_mod)868 void PyC_MainModule_Backup(PyObject **main_mod)
869 {
870   PyObject *modules = PyImport_GetModuleDict();
871   *main_mod = PyDict_GetItemString(modules, "__main__");
872   Py_XINCREF(*main_mod); /* don't free */
873 }
874 
PyC_MainModule_Restore(PyObject * main_mod)875 void PyC_MainModule_Restore(PyObject *main_mod)
876 {
877   PyObject *modules = PyImport_GetModuleDict();
878   PyDict_SetItemString(modules, "__main__", main_mod);
879   Py_XDECREF(main_mod);
880 }
881 
882 /** \} */
883 
884 /* -------------------------------------------------------------------- */
885 /** \name #Py_SetPythonHome Wrapper
886  * \{ */
887 
888 /**
889  * - Must be called before #Py_Initialize.
890  * - Expects output of `BKE_appdir_folder_id(BLENDER_PYTHON, NULL)`.
891  * - Note that the `PYTHONPATH` environment variable isn't reliable, see T31506.
892  *   Use #Py_SetPythonHome instead.
893  */
PyC_SetHomePath(const char * py_path_bundle)894 void PyC_SetHomePath(const char *py_path_bundle)
895 {
896   if (py_path_bundle == NULL) {
897     /* Common enough to have bundled *nix python but complain on OSX/Win */
898 #  if defined(__APPLE__) || defined(_WIN32)
899     fprintf(stderr,
900             "Warning! bundled python not found and is expected on this platform. "
901             "(if you built with CMake: 'install' target may have not been built)\n");
902 #  endif
903     return;
904   }
905   /* set the environment path */
906   printf("found bundled python: %s\n", py_path_bundle);
907 
908 #  ifdef __APPLE__
909   /* OSX allow file/directory names to contain : character (represented as / in the Finder)
910    * but current Python lib (release 3.1.1) doesn't handle these correctly */
911   if (strchr(py_path_bundle, ':')) {
912     fprintf(stderr,
913             "Warning! Blender application is located in a path containing ':' or '/' chars\n"
914             "This may make python import function fail\n");
915   }
916 #  endif
917 
918   {
919     wchar_t py_path_bundle_wchar[1024];
920 
921     /* Can't use this, on linux gives bug: T23018,
922      * TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 2008 */
923     /* mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); */
924 
925     BLI_strncpy_wchar_from_utf8(
926         py_path_bundle_wchar, py_path_bundle, ARRAY_SIZE(py_path_bundle_wchar));
927 
928     Py_SetPythonHome(py_path_bundle_wchar);
929     // printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar);
930   }
931 }
932 
PyC_IsInterpreterActive(void)933 bool PyC_IsInterpreterActive(void)
934 {
935   /* instead of PyThreadState_Get, which calls Py_FatalError */
936   return (PyThreadState_GetDict() != NULL);
937 }
938 
939 /** \} */
940 
941 /* -------------------------------------------------------------------- */
942 /** \name #Py_SetPythonHome Wrapper
943  * \{ */
944 
945 /* Would be nice if python had this built in
946  * See: https://wiki.blender.org/wiki/Tools/Debugging/PyFromC
947  */
PyC_RunQuicky(const char * filepath,int n,...)948 void PyC_RunQuicky(const char *filepath, int n, ...)
949 {
950   FILE *fp = fopen(filepath, "r");
951 
952   if (fp) {
953     const PyGILState_STATE gilstate = PyGILState_Ensure();
954 
955     va_list vargs;
956 
957     Py_ssize_t *sizes = PyMem_MALLOC(sizeof(*sizes) * (n / 2));
958     int i;
959 
960     PyObject *py_dict = PyC_DefaultNameSpace(filepath);
961     PyObject *values = PyList_New(n / 2); /* namespace owns this, don't free */
962 
963     PyObject *py_result, *ret;
964 
965     PyObject *struct_mod = PyImport_ImportModule("struct");
966     PyObject *calcsize = PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */
967     PyObject *pack = PyObject_GetAttrString(struct_mod, "pack");         /* struct.pack */
968     PyObject *unpack = PyObject_GetAttrString(struct_mod, "unpack");     /* struct.unpack */
969 
970     Py_DECREF(struct_mod);
971 
972     va_start(vargs, n);
973     for (i = 0; i * 2 < n; i++) {
974       const char *format = va_arg(vargs, char *);
975       void *ptr = va_arg(vargs, void *);
976 
977       ret = PyObject_CallFunction(calcsize, "s", format);
978 
979       if (ret) {
980         sizes[i] = PyLong_AsLong(ret);
981         Py_DECREF(ret);
982         ret = PyObject_CallFunction(unpack, "sy#", format, (char *)ptr, sizes[i]);
983       }
984 
985       if (ret == NULL) {
986         printf("%s error, line:%d\n", __func__, __LINE__);
987         PyErr_Print();
988         PyErr_Clear();
989 
990         PyList_SET_ITEM(values, i, Py_INCREF_RET(Py_None)); /* hold user */
991 
992         sizes[i] = 0;
993       }
994       else {
995         if (PyTuple_GET_SIZE(ret) == 1) {
996           /* convenience, convert single tuples into single values */
997           PyObject *tmp = PyTuple_GET_ITEM(ret, 0);
998           Py_INCREF(tmp);
999           Py_DECREF(ret);
1000           ret = tmp;
1001         }
1002 
1003         PyList_SET_ITEM(values, i, ret); /* hold user */
1004       }
1005     }
1006     va_end(vargs);
1007 
1008     /* set the value so we can access it */
1009     PyDict_SetItemString(py_dict, "values", values);
1010     Py_DECREF(values);
1011 
1012     py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict);
1013 
1014     fclose(fp);
1015 
1016     if (py_result) {
1017 
1018       /* we could skip this but then only slice assignment would work
1019        * better not be so strict */
1020       values = PyDict_GetItemString(py_dict, "values");
1021 
1022       if (values && PyList_Check(values)) {
1023 
1024         /* don't use the result */
1025         Py_DECREF(py_result);
1026         py_result = NULL;
1027 
1028         /* now get the values back */
1029         va_start(vargs, n);
1030         for (i = 0; i * 2 < n; i++) {
1031           const char *format = va_arg(vargs, char *);
1032           void *ptr = va_arg(vargs, void *);
1033 
1034           PyObject *item;
1035           PyObject *item_new;
1036           /* prepend the string formatting and remake the tuple */
1037           item = PyList_GET_ITEM(values, i);
1038           if (PyTuple_CheckExact(item)) {
1039             int ofs = PyTuple_GET_SIZE(item);
1040             item_new = PyTuple_New(ofs + 1);
1041             while (ofs--) {
1042               PyObject *member = PyTuple_GET_ITEM(item, ofs);
1043               PyTuple_SET_ITEM(item_new, ofs + 1, member);
1044               Py_INCREF(member);
1045             }
1046 
1047             PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format));
1048           }
1049           else {
1050             item_new = Py_BuildValue("sO", format, item);
1051           }
1052 
1053           ret = PyObject_Call(pack, item_new, NULL);
1054 
1055           if (ret) {
1056             /* copy the bytes back into memory */
1057             memcpy(ptr, PyBytes_AS_STRING(ret), sizes[i]);
1058             Py_DECREF(ret);
1059           }
1060           else {
1061             printf("%s error on arg '%d', line:%d\n", __func__, i, __LINE__);
1062             PyC_ObSpit("failed converting:", item_new);
1063             PyErr_Print();
1064             PyErr_Clear();
1065           }
1066 
1067           Py_DECREF(item_new);
1068         }
1069         va_end(vargs);
1070       }
1071       else {
1072         printf("%s error, 'values' not a list, line:%d\n", __func__, __LINE__);
1073       }
1074     }
1075     else {
1076       printf("%s error line:%d\n", __func__, __LINE__);
1077       PyErr_Print();
1078       PyErr_Clear();
1079     }
1080 
1081     Py_DECREF(calcsize);
1082     Py_DECREF(pack);
1083     Py_DECREF(unpack);
1084 
1085     PyMem_FREE(sizes);
1086 
1087     PyGILState_Release(gilstate);
1088   }
1089   else {
1090     fprintf(stderr, "%s: '%s' missing\n", __func__, filepath);
1091   }
1092 }
1093 
1094 /* generic function to avoid depending on RNA */
PyC_RNA_AsPointer(PyObject * value,const char * type_name)1095 void *PyC_RNA_AsPointer(PyObject *value, const char *type_name)
1096 {
1097   PyObject *as_pointer;
1098   PyObject *pointer;
1099 
1100   if (STREQ(Py_TYPE(value)->tp_name, type_name) &&
1101       (as_pointer = PyObject_GetAttrString(value, "as_pointer")) != NULL &&
1102       PyCallable_Check(as_pointer)) {
1103     void *result = NULL;
1104 
1105     /* must be a 'type_name' object */
1106     pointer = PyObject_CallObject(as_pointer, NULL);
1107     Py_DECREF(as_pointer);
1108 
1109     if (!pointer) {
1110       PyErr_SetString(PyExc_SystemError, "value.as_pointer() failed");
1111       return NULL;
1112     }
1113     result = PyLong_AsVoidPtr(pointer);
1114     Py_DECREF(pointer);
1115     if (!result) {
1116       PyErr_SetString(PyExc_SystemError, "value.as_pointer() failed");
1117     }
1118 
1119     return result;
1120   }
1121 
1122   PyErr_Format(PyExc_TypeError,
1123                "expected '%.200s' type found '%.200s' instead",
1124                type_name,
1125                Py_TYPE(value)->tp_name);
1126   return NULL;
1127 }
1128 
1129 /** \} */
1130 
1131 /* -------------------------------------------------------------------- */
1132 /** \name Flag Set Utilities (#PyC_FlagSet)
1133  *
1134  * Convert to/from Python set of strings to an int flag.
1135  * \{ */
1136 
PyC_FlagSet_AsString(PyC_FlagSet * item)1137 PyObject *PyC_FlagSet_AsString(PyC_FlagSet *item)
1138 {
1139   PyObject *py_items = PyList_New(0);
1140   for (; item->identifier; item++) {
1141     PyList_APPEND(py_items, PyUnicode_FromString(item->identifier));
1142   }
1143   PyObject *py_string = PyObject_Repr(py_items);
1144   Py_DECREF(py_items);
1145   return py_string;
1146 }
1147 
PyC_FlagSet_ValueFromID_int(PyC_FlagSet * item,const char * identifier,int * r_value)1148 int PyC_FlagSet_ValueFromID_int(PyC_FlagSet *item, const char *identifier, int *r_value)
1149 {
1150   for (; item->identifier; item++) {
1151     if (STREQ(item->identifier, identifier)) {
1152       *r_value = item->value;
1153       return 1;
1154     }
1155   }
1156 
1157   return 0;
1158 }
1159 
PyC_FlagSet_ValueFromID(PyC_FlagSet * item,const char * identifier,int * r_value,const char * error_prefix)1160 int PyC_FlagSet_ValueFromID(PyC_FlagSet *item,
1161                             const char *identifier,
1162                             int *r_value,
1163                             const char *error_prefix)
1164 {
1165   if (PyC_FlagSet_ValueFromID_int(item, identifier, r_value) == 0) {
1166     PyObject *enum_str = PyC_FlagSet_AsString(item);
1167     PyErr_Format(
1168         PyExc_ValueError, "%s: '%.200s' not found in (%U)", error_prefix, identifier, enum_str);
1169     Py_DECREF(enum_str);
1170     return -1;
1171   }
1172 
1173   return 0;
1174 }
1175 
PyC_FlagSet_ToBitfield(PyC_FlagSet * items,PyObject * value,int * r_value,const char * error_prefix)1176 int PyC_FlagSet_ToBitfield(PyC_FlagSet *items,
1177                            PyObject *value,
1178                            int *r_value,
1179                            const char *error_prefix)
1180 {
1181   /* set of enum items, concatenate all values with OR */
1182   int ret, flag = 0;
1183 
1184   /* set looping */
1185   Py_ssize_t pos = 0;
1186   Py_ssize_t hash = 0;
1187   PyObject *key;
1188 
1189   if (!PySet_Check(value)) {
1190     PyErr_Format(PyExc_TypeError,
1191                  "%.200s expected a set, not %.200s",
1192                  error_prefix,
1193                  Py_TYPE(value)->tp_name);
1194     return -1;
1195   }
1196 
1197   *r_value = 0;
1198 
1199   while (_PySet_NextEntry(value, &pos, &key, &hash)) {
1200     const char *param = _PyUnicode_AsString(key);
1201 
1202     if (param == NULL) {
1203       PyErr_Format(PyExc_TypeError,
1204                    "%.200s set must contain strings, not %.200s",
1205                    error_prefix,
1206                    Py_TYPE(key)->tp_name);
1207       return -1;
1208     }
1209 
1210     if (PyC_FlagSet_ValueFromID(items, param, &ret, error_prefix) < 0) {
1211       return -1;
1212     }
1213 
1214     flag |= ret;
1215   }
1216 
1217   *r_value = flag;
1218   return 0;
1219 }
1220 
PyC_FlagSet_FromBitfield(PyC_FlagSet * items,int flag)1221 PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag)
1222 {
1223   PyObject *ret = PySet_New(NULL);
1224   PyObject *pystr;
1225 
1226   for (; items->identifier; items++) {
1227     if (items->value & flag) {
1228       pystr = PyUnicode_FromString(items->identifier);
1229       PySet_Add(ret, pystr);
1230       Py_DECREF(pystr);
1231     }
1232   }
1233 
1234   return ret;
1235 }
1236 
1237 /** \} */
1238 
1239 /* -------------------------------------------------------------------- */
1240 /** \name Run String (Evaluate to Primitive Types)
1241  * \{ */
1242 
1243 /**
1244  * \return success
1245  *
1246  * \note it is caller's responsibility to acquire & release GIL!
1247  */
PyC_RunString_AsNumber(const char * imports[],const char * expr,const char * filename,double * r_value)1248 bool PyC_RunString_AsNumber(const char *imports[],
1249                             const char *expr,
1250                             const char *filename,
1251                             double *r_value)
1252 {
1253   PyObject *py_dict, *mod, *retval;
1254   bool ok = true;
1255   PyObject *main_mod = NULL;
1256 
1257   PyC_MainModule_Backup(&main_mod);
1258 
1259   py_dict = PyC_DefaultNameSpace(filename);
1260 
1261   mod = PyImport_ImportModule("math");
1262   if (mod) {
1263     PyDict_Merge(py_dict, PyModule_GetDict(mod), 0); /* 0 - don't overwrite existing values */
1264     Py_DECREF(mod);
1265   }
1266   else { /* highly unlikely but possibly */
1267     PyErr_Print();
1268     PyErr_Clear();
1269   }
1270 
1271   if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
1272     ok = false;
1273   }
1274   else if ((retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict)) == NULL) {
1275     ok = false;
1276   }
1277   else {
1278     double val;
1279 
1280     if (PyTuple_Check(retval)) {
1281       /* Users my have typed in 10km, 2m
1282        * add up all values */
1283       int i;
1284       val = 0.0;
1285 
1286       for (i = 0; i < PyTuple_GET_SIZE(retval); i++) {
1287         const double val_item = PyFloat_AsDouble(PyTuple_GET_ITEM(retval, i));
1288         if (val_item == -1 && PyErr_Occurred()) {
1289           val = -1;
1290           break;
1291         }
1292         val += val_item;
1293       }
1294     }
1295     else {
1296       val = PyFloat_AsDouble(retval);
1297     }
1298     Py_DECREF(retval);
1299 
1300     if (val == -1 && PyErr_Occurred()) {
1301       ok = false;
1302     }
1303     else if (!isfinite(val)) {
1304       *r_value = 0.0;
1305     }
1306     else {
1307       *r_value = val;
1308     }
1309   }
1310 
1311   PyC_MainModule_Restore(main_mod);
1312 
1313   return ok;
1314 }
1315 
PyC_RunString_AsIntPtr(const char * imports[],const char * expr,const char * filename,intptr_t * r_value)1316 bool PyC_RunString_AsIntPtr(const char *imports[],
1317                             const char *expr,
1318                             const char *filename,
1319                             intptr_t *r_value)
1320 {
1321   PyObject *py_dict, *retval;
1322   bool ok = true;
1323   PyObject *main_mod = NULL;
1324 
1325   PyC_MainModule_Backup(&main_mod);
1326 
1327   py_dict = PyC_DefaultNameSpace(filename);
1328 
1329   if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
1330     ok = false;
1331   }
1332   else if ((retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict)) == NULL) {
1333     ok = false;
1334   }
1335   else {
1336     intptr_t val;
1337 
1338     val = (intptr_t)PyLong_AsVoidPtr(retval);
1339     if (val == 0 && PyErr_Occurred()) {
1340       ok = false;
1341     }
1342     else {
1343       *r_value = val;
1344     }
1345 
1346     Py_DECREF(retval);
1347   }
1348 
1349   PyC_MainModule_Restore(main_mod);
1350 
1351   return ok;
1352 }
1353 
PyC_RunString_AsStringAndSize(const char * imports[],const char * expr,const char * filename,char ** r_value,size_t * r_value_size)1354 bool PyC_RunString_AsStringAndSize(const char *imports[],
1355                                    const char *expr,
1356                                    const char *filename,
1357                                    char **r_value,
1358                                    size_t *r_value_size)
1359 {
1360   PyObject *py_dict, *retval;
1361   bool ok = true;
1362   PyObject *main_mod = NULL;
1363 
1364   PyC_MainModule_Backup(&main_mod);
1365 
1366   py_dict = PyC_DefaultNameSpace(filename);
1367 
1368   if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
1369     ok = false;
1370   }
1371   else if ((retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict)) == NULL) {
1372     ok = false;
1373   }
1374   else {
1375     const char *val;
1376     Py_ssize_t val_len;
1377 
1378     val = _PyUnicode_AsStringAndSize(retval, &val_len);
1379     if (val == NULL && PyErr_Occurred()) {
1380       ok = false;
1381     }
1382     else {
1383       char *val_alloc = MEM_mallocN(val_len + 1, __func__);
1384       memcpy(val_alloc, val, val_len + 1);
1385       *r_value = val_alloc;
1386       *r_value_size = val_len;
1387     }
1388 
1389     Py_DECREF(retval);
1390   }
1391 
1392   PyC_MainModule_Restore(main_mod);
1393 
1394   return ok;
1395 }
1396 
PyC_RunString_AsString(const char * imports[],const char * expr,const char * filename,char ** r_value)1397 bool PyC_RunString_AsString(const char *imports[],
1398                             const char *expr,
1399                             const char *filename,
1400                             char **r_value)
1401 {
1402   size_t value_size;
1403   return PyC_RunString_AsStringAndSize(imports, expr, filename, r_value, &value_size);
1404 }
1405 
1406 /** \} */
1407 
1408 #endif /* #ifndef MATH_STANDALONE */
1409 
1410 /* -------------------------------------------------------------------- */
1411 /** \name Int Conversion
1412  *
1413  * \note Python doesn't provide overflow checks for specific bit-widths.
1414  *
1415  * \{ */
1416 
1417 /* Compiler optimizes out redundant checks. */
1418 #ifdef __GNUC__
1419 #  pragma warning(push)
1420 #  pragma GCC diagnostic ignored "-Wtype-limits"
1421 #endif
1422 
1423 /**
1424  * Don't use `bool` return type, so -1 can be used as an error value.
1425  */
PyC_Long_AsBool(PyObject * value)1426 int PyC_Long_AsBool(PyObject *value)
1427 {
1428   const int test = _PyLong_AsInt(value);
1429   if (UNLIKELY((uint)test > 1)) {
1430     PyErr_SetString(PyExc_TypeError, "Python number not a bool (0/1)");
1431     return -1;
1432   }
1433   return test;
1434 }
1435 
PyC_Long_AsI8(PyObject * value)1436 int8_t PyC_Long_AsI8(PyObject *value)
1437 {
1438   const int test = _PyLong_AsInt(value);
1439   if (UNLIKELY(test < INT8_MIN || test > INT8_MAX)) {
1440     PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int8");
1441     return -1;
1442   }
1443   return (int8_t)test;
1444 }
1445 
PyC_Long_AsI16(PyObject * value)1446 int16_t PyC_Long_AsI16(PyObject *value)
1447 {
1448   const int test = _PyLong_AsInt(value);
1449   if (UNLIKELY(test < INT16_MIN || test > INT16_MAX)) {
1450     PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int16");
1451     return -1;
1452   }
1453   return (int16_t)test;
1454 }
1455 
1456 /* Inlined in header:
1457  * PyC_Long_AsI32
1458  * PyC_Long_AsI64
1459  */
1460 
PyC_Long_AsU8(PyObject * value)1461 uint8_t PyC_Long_AsU8(PyObject *value)
1462 {
1463   const ulong test = PyLong_AsUnsignedLong(value);
1464   if (UNLIKELY(test > UINT8_MAX)) {
1465     PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C uint8");
1466     return (uint8_t)-1;
1467   }
1468   return (uint8_t)test;
1469 }
1470 
PyC_Long_AsU16(PyObject * value)1471 uint16_t PyC_Long_AsU16(PyObject *value)
1472 {
1473   const ulong test = PyLong_AsUnsignedLong(value);
1474   if (UNLIKELY(test > UINT16_MAX)) {
1475     PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C uint16");
1476     return (uint16_t)-1;
1477   }
1478   return (uint16_t)test;
1479 }
1480 
PyC_Long_AsU32(PyObject * value)1481 uint32_t PyC_Long_AsU32(PyObject *value)
1482 {
1483   const ulong test = PyLong_AsUnsignedLong(value);
1484   if (UNLIKELY(test > UINT32_MAX)) {
1485     PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C uint32");
1486     return (uint32_t)-1;
1487   }
1488   return (uint32_t)test;
1489 }
1490 
1491 /* Inlined in header:
1492  * PyC_Long_AsU64
1493  */
1494 
1495 #ifdef __GNUC__
1496 #  pragma warning(pop)
1497 #endif
1498 
1499 /** \} */
1500 
1501 /* -------------------------------------------------------------------- */
1502 /** \name Py_buffer Utils
1503  *
1504  * \{ */
1505 
PyC_StructFmt_type_from_str(const char * typestr)1506 char PyC_StructFmt_type_from_str(const char *typestr)
1507 {
1508   switch (typestr[0]) {
1509     case '!':
1510     case '<':
1511     case '=':
1512     case '>':
1513     case '@':
1514       return typestr[1];
1515     default:
1516       return typestr[0];
1517   }
1518 }
1519 
PyC_StructFmt_type_is_float_any(char format)1520 bool PyC_StructFmt_type_is_float_any(char format)
1521 {
1522   switch (format) {
1523     case 'f':
1524     case 'd':
1525     case 'e':
1526       return true;
1527     default:
1528       return false;
1529   }
1530 }
1531 
PyC_StructFmt_type_is_int_any(char format)1532 bool PyC_StructFmt_type_is_int_any(char format)
1533 {
1534   switch (format) {
1535     case 'i':
1536     case 'I':
1537     case 'l':
1538     case 'L':
1539     case 'h':
1540     case 'H':
1541     case 'b':
1542     case 'B':
1543     case 'q':
1544     case 'Q':
1545     case 'n':
1546     case 'N':
1547     case 'P':
1548       return true;
1549     default:
1550       return false;
1551   }
1552 }
1553 
PyC_StructFmt_type_is_byte(char format)1554 bool PyC_StructFmt_type_is_byte(char format)
1555 {
1556   switch (format) {
1557     case 'c':
1558     case 's':
1559     case 'p':
1560       return true;
1561     default:
1562       return false;
1563   }
1564 }
1565 
PyC_StructFmt_type_is_bool(char format)1566 bool PyC_StructFmt_type_is_bool(char format)
1567 {
1568   switch (format) {
1569     case '?':
1570       return true;
1571     default:
1572       return false;
1573   }
1574 }
1575 
1576 /** \} */
1577