diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-02-22 13:15:46 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-02-22 13:15:46 +0400 |
commit | 3788adb8cbe227e68d6c4442d8896f8d00c502fb (patch) | |
tree | 371744d2696aeff91ebf2c0386a2cb6ecd7b15bd /source | |
parent | 1f40f0143575d73a6efa63dcfa960c77ae62e086 (diff) |
utility functions to convert between flags / sets, without depending on RNA API.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/python/generic/py_capi_utils.c | 96 | ||||
-rw-r--r-- | source/blender/python/generic/py_capi_utils.h | 12 |
2 files changed, 108 insertions, 0 deletions
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index e79bad57ee0..3802bd80b9e 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -682,3 +682,99 @@ void *PyC_RNA_AsPointer(PyObject *value, const char *type_name) return NULL; } } + + +/* PyC_FlagSet_* functions - so flags/sets can be interchanged in a generic way */ +#include "BLI_dynstr.h" +#include "MEM_guardedalloc.h" + +char *PyC_FlagSet_AsString(PyC_FlagSet *item) +{ + DynStr *dynstr = BLI_dynstr_new(); + PyC_FlagSet *e; + char *cstring; + + for (e = item; item->identifier; item++) { + BLI_dynstr_appendf(dynstr, (e == item) ? "'%s'" : ", '%s'", item->identifier); + } + + cstring = BLI_dynstr_get_cstring(dynstr); + BLI_dynstr_free(dynstr); + return cstring; +} + +int PyC_FlagSet_ValueFromID_int(PyC_FlagSet *item, const char *identifier, int *value) +{ + for( ; item->identifier; item++) { + if(strcmp(item->identifier, identifier) == 0) { + *value = item->value; + return 1; + } + } + + return 0; +} + +int PyC_FlagSet_ValueFromID(PyC_FlagSet *item, const char *identifier, int *value, const char *error_prefix) +{ + if (PyC_FlagSet_ValueFromID_int(item, identifier, value) == 0) { + const char *enum_str = PyC_FlagSet_AsString(item); + PyErr_Format(PyExc_ValueError, + "%s: '%.200s' not found in (%s)", + error_prefix, identifier, enum_str); + MEM_freeN((void *)enum_str); + return -1; + } + + return 0; +} + +/* 'value' _must_ be a set type, error check before calling */ +int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, const char *error_prefix) +{ + /* set of enum items, concatenate all values with OR */ + int ret, flag = 0; + + /* set looping */ + Py_ssize_t pos = 0; + Py_ssize_t hash = 0; + PyObject *key; + + *r_value = 0; + + while (_PySet_NextEntry(value, &pos, &key, &hash)) { + const char *param = _PyUnicode_AsString(key); + + if (param == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s expected a string, not %.200s", + error_prefix, Py_TYPE(key)->tp_name); + return -1; + } + + if (PyC_FlagSet_ValueFromID(items, param, &ret, error_prefix) < 0) { + return -1; + } + + flag |= ret; + } + + *r_value = flag; + return 0; +} + +PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag) +{ + PyObject *ret = PySet_New(NULL); + PyObject *pystr; + + for ( ; items->identifier; items++) { + if (items->value & flag) { + pystr = PyUnicode_FromString(items->identifier); + PySet_Add(ret, pystr); + Py_DECREF(pystr); + } + } + + return ret; +} diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index 18eac6d42f8..9ef171256aa 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -56,4 +56,16 @@ void PyC_SetHomePath(const char *py_path_bundle); void *PyC_RNA_AsPointer(PyObject *value, const char *type_name); +/* flag / set --- interchange */ +typedef struct PyC_FlagSet { + int value; + const char *identifier; +} PyC_FlagSet; + +char *PyC_FlagSet_AsString(PyC_FlagSet *item); +int PyC_FlagSet_ValueFromID_int(PyC_FlagSet *item, const char *identifier, int *value); +int PyC_FlagSet_ValueFromID(PyC_FlagSet *item, const char *identifier, int *value, const char *error_prefix); +int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, const char *error_prefix); +PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag); + #endif // __PY_CAPI_UTILS_H__ |