Merge branch 'master' into blender2.8
This commit is contained in:
commit
29aa531e51
|
@ -152,8 +152,13 @@ void IDP_Reset(IDProperty *prop, const IDProperty *reference);
|
|||
# define IDP_Id(prop) ((ID *) (prop)->data.pointer)
|
||||
#endif
|
||||
|
||||
/* for printout/logging only */
|
||||
char *IDP_reprN(const struct IDProperty *prop);
|
||||
/* Format IDProperty as strings */
|
||||
char *IDP_reprN(
|
||||
const struct IDProperty *prop, uint *r_len);
|
||||
void IDP_repr_fn(
|
||||
const IDProperty *prop,
|
||||
void (*str_append_fn)(void *user_data, const char *str, uint str_len),
|
||||
void *user_data);
|
||||
void IDP_print(const struct IDProperty *prop);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -119,6 +119,7 @@ set(SRC
|
|||
intern/icons_rasterize.c
|
||||
intern/idcode.c
|
||||
intern/idprop.c
|
||||
intern/idprop_utils.c
|
||||
intern/image.c
|
||||
intern/image_gen.c
|
||||
intern/ipo.c
|
||||
|
|
|
@ -1107,17 +1107,3 @@ void IDP_Reset(IDProperty *prop, const IDProperty *reference)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* We could write a C version, see: idprop_py_api.c */
|
||||
#ifndef WITH_PYTHON
|
||||
char *IDP_reprN(IDProperty *UNUSED(prop))
|
||||
{
|
||||
return BLI_strdup("<unsupported>");
|
||||
}
|
||||
|
||||
void IDP_print(IDProperty *prop)
|
||||
{
|
||||
char *repr = IDP_reprN(prop);
|
||||
printf("IDProperty(%p): %s\n", prop, repr);
|
||||
MEM_freeN(repr);
|
||||
}
|
||||
#endif /* WITH_PYTHON */
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/blenkernel/intern/idprop_utils.c
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_dynstr.h"
|
||||
|
||||
#include "BKE_idprop.h"
|
||||
#include "BKE_idcode.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_strict_flags.h"
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name IDProp Repr
|
||||
*
|
||||
* Convert an IDProperty to a string.
|
||||
*
|
||||
* Output should be a valid Python literal
|
||||
* (with minor exceptions - float nan for eg).
|
||||
* \{ */
|
||||
|
||||
struct ReprState {
|
||||
void (*str_append_fn)(void *user_data, const char *str, uint str_len);
|
||||
void *user_data;
|
||||
/* Big enough to format any primitive type. */
|
||||
char buf[128];
|
||||
};
|
||||
|
||||
static void idp_str_append_escape(struct ReprState *state, const char *str, const uint str_len, bool quote)
|
||||
{
|
||||
if (quote) {
|
||||
state->str_append_fn(state->user_data, "\"", 1);
|
||||
}
|
||||
uint i_prev = 0, i = 0;
|
||||
while (i < str_len) {
|
||||
const char c = str[i];
|
||||
if (c == '"') {
|
||||
if (i_prev != i) {
|
||||
state->str_append_fn(state->user_data, str + i_prev, i - i_prev);
|
||||
}
|
||||
state->str_append_fn(state->user_data, "\\\"", 2);
|
||||
i_prev = i + 1;
|
||||
}
|
||||
else if (c == '\\') {
|
||||
if (i_prev != i) {
|
||||
state->str_append_fn(state->user_data, str + i_prev, i - i_prev);
|
||||
}
|
||||
state->str_append_fn(state->user_data, "\\\\", 2);
|
||||
i_prev = i + 1;
|
||||
}
|
||||
else if (c < 32) {
|
||||
if (i_prev != i) {
|
||||
state->str_append_fn(state->user_data, str + i_prev, i - i_prev);
|
||||
}
|
||||
char buf[5];
|
||||
uint len = (uint)BLI_snprintf_rlen(buf, sizeof(buf), "\\x%02x", c);
|
||||
BLI_assert(len == 4);
|
||||
state->str_append_fn(state->user_data, buf, len);
|
||||
i_prev = i + 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
state->str_append_fn(state->user_data, str + i_prev, i - i_prev);
|
||||
if (quote) {
|
||||
state->str_append_fn(state->user_data, "\"", 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void idp_repr_fn_recursive(struct ReprState *state, const IDProperty *prop)
|
||||
{
|
||||
/* Note: 'strlen' will be calculated at compile time for literals. */
|
||||
#define STR_APPEND_STR(str) { \
|
||||
state->str_append_fn(state->user_data, str, (uint)strlen(str)); \
|
||||
} ((void)0)
|
||||
|
||||
#define STR_APPEND_STR_QUOTE(str) { \
|
||||
idp_str_append_escape(state, str, (uint)strlen(str), true); \
|
||||
} ((void)0)
|
||||
|
||||
#define STR_APPEND_FMT(format, ...) { \
|
||||
const uint len = (uint)BLI_snprintf_rlen(state->buf, sizeof(state->buf), format, __VA_ARGS__); \
|
||||
state->str_append_fn(state->user_data, state->buf, len); \
|
||||
} ((void)0)
|
||||
|
||||
switch (prop->type) {
|
||||
case IDP_STRING:
|
||||
{
|
||||
STR_APPEND_STR_QUOTE(IDP_String(prop));
|
||||
break;
|
||||
}
|
||||
case IDP_INT:
|
||||
{
|
||||
STR_APPEND_FMT("%d", IDP_Int(prop));
|
||||
break;
|
||||
}
|
||||
case IDP_FLOAT:
|
||||
{
|
||||
STR_APPEND_FMT("%g", (double)IDP_Float(prop));
|
||||
break;
|
||||
}
|
||||
case IDP_DOUBLE:
|
||||
{
|
||||
STR_APPEND_FMT("%g", IDP_Double(prop));
|
||||
break;
|
||||
}
|
||||
case IDP_ARRAY:
|
||||
{
|
||||
STR_APPEND_STR("[");
|
||||
switch (prop->subtype) {
|
||||
case IDP_INT:
|
||||
for (const int *v = prop->data.pointer, *v_end = v + prop->len; v != v_end; v++) {
|
||||
if (v != prop->data.pointer) {
|
||||
STR_APPEND_STR(", ");
|
||||
}
|
||||
STR_APPEND_FMT("%d", *v);
|
||||
}
|
||||
break;
|
||||
case IDP_FLOAT:
|
||||
for (const float *v = prop->data.pointer, *v_end = v + prop->len; v != v_end; v++) {
|
||||
if (v != prop->data.pointer) {
|
||||
STR_APPEND_STR(", ");
|
||||
}
|
||||
STR_APPEND_FMT("%g", (double)*v);
|
||||
}
|
||||
break;
|
||||
case IDP_DOUBLE:
|
||||
for (const double *v = prop->data.pointer, *v_end = v + prop->len; v != v_end; v++) {
|
||||
if (v != prop->data.pointer) {
|
||||
STR_APPEND_STR(", ");
|
||||
}
|
||||
STR_APPEND_FMT("%g", *v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
STR_APPEND_STR("]");
|
||||
break;
|
||||
}
|
||||
case IDP_IDPARRAY:
|
||||
{
|
||||
STR_APPEND_STR("[");
|
||||
for (const IDProperty *v = prop->data.pointer, *v_end = v + prop->len; v != v_end; v++) {
|
||||
if (v != prop->data.pointer) {
|
||||
STR_APPEND_STR(", ");
|
||||
}
|
||||
idp_repr_fn_recursive(state, v);
|
||||
}
|
||||
STR_APPEND_STR("]");
|
||||
break;
|
||||
}
|
||||
case IDP_GROUP:
|
||||
{
|
||||
STR_APPEND_STR("{");
|
||||
for (const IDProperty *subprop = prop->data.group.first; subprop; subprop = subprop->next) {
|
||||
if (subprop != prop->data.group.first) {
|
||||
STR_APPEND_STR(", ");
|
||||
}
|
||||
STR_APPEND_STR_QUOTE(subprop->name);
|
||||
STR_APPEND_STR(": ");
|
||||
idp_repr_fn_recursive(state, subprop);
|
||||
}
|
||||
STR_APPEND_STR("}");
|
||||
break;
|
||||
}
|
||||
case IDP_ID:
|
||||
{
|
||||
const ID *id = prop->data.pointer;
|
||||
STR_APPEND_STR("bpy.data.");
|
||||
STR_APPEND_STR(BKE_idcode_to_name_plural(GS(id->name)));
|
||||
STR_APPEND_STR("[");
|
||||
STR_APPEND_STR_QUOTE(id->name + 2);
|
||||
STR_APPEND_STR("]");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#undef STR_APPEND_STR
|
||||
#undef STR_APPEND_STR_QUOTE
|
||||
#undef STR_APPEND_FMT
|
||||
|
||||
}
|
||||
|
||||
void IDP_repr_fn(
|
||||
const IDProperty *prop,
|
||||
void (*str_append_fn)(void *user_data, const char *str, uint str_len),
|
||||
void *user_data)
|
||||
{
|
||||
struct ReprState state = {
|
||||
.str_append_fn = str_append_fn,
|
||||
.user_data = user_data,
|
||||
};
|
||||
idp_repr_fn_recursive(&state, prop);
|
||||
}
|
||||
|
||||
static void repr_str(void *user_data, const char *str, uint len)
|
||||
{
|
||||
BLI_dynstr_nappend(user_data, str, (int)len);
|
||||
}
|
||||
|
||||
char *IDP_reprN(const IDProperty *prop, uint *r_len)
|
||||
{
|
||||
DynStr *ds = BLI_dynstr_new();
|
||||
IDP_repr_fn(prop, repr_str, ds);
|
||||
char *cstring = BLI_dynstr_get_cstring(ds);
|
||||
if (r_len != NULL) {
|
||||
*r_len = (uint)BLI_dynstr_get_len(ds);
|
||||
}
|
||||
BLI_dynstr_free(ds);
|
||||
return cstring;
|
||||
}
|
||||
|
||||
void IDP_print(const IDProperty *prop)
|
||||
{
|
||||
char *repr = IDP_reprN(prop, NULL);
|
||||
printf("IDProperty(%p): ", prop);
|
||||
puts(repr);
|
||||
MEM_freeN(repr);
|
||||
}
|
||||
|
||||
/** \} */
|
|
@ -1806,49 +1806,3 @@ PyObject *BPyInit_idprop(void)
|
|||
|
||||
return mod;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* debug only function */
|
||||
|
||||
char *IDP_reprN(const IDProperty *prop)
|
||||
{
|
||||
if (prop == NULL) {
|
||||
return BLI_strdup("None");
|
||||
}
|
||||
|
||||
PyGILState_STATE gilstate;
|
||||
bool use_gil = true; /* !PyC_IsInterpreterActive(); */
|
||||
PyObject *ret_dict;
|
||||
PyObject *ret_str;
|
||||
|
||||
if (use_gil) {
|
||||
gilstate = PyGILState_Ensure();
|
||||
}
|
||||
|
||||
/* Note: non-const cast is safe here since we only repr the result. */
|
||||
/* to_dict() */
|
||||
ret_dict = BPy_IDGroup_MapDataToPy((IDProperty *)prop);
|
||||
ret_str = PyObject_Repr(ret_dict);
|
||||
Py_DECREF(ret_dict);
|
||||
|
||||
Py_ssize_t res_str_len = 0;
|
||||
char *res_str_bytes = _PyUnicode_AsStringAndSize(ret_str, &res_str_len);
|
||||
|
||||
res_str_bytes = BLI_strdupn(res_str_bytes, res_str_len);
|
||||
|
||||
Py_DECREF(ret_str);
|
||||
|
||||
if (use_gil) {
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
return res_str_bytes;
|
||||
}
|
||||
|
||||
|
||||
void IDP_print(const IDProperty *prop)
|
||||
{
|
||||
char *repr = IDP_reprN(prop);
|
||||
printf("IDProperty(%p): %s\n", prop, repr);
|
||||
MEM_freeN(repr);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue