2 * This file is part of the libsigrokdecode project.
4 * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "libsigrokdecode-internal.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
22 #include "libsigrokdecode.h"
26 static char *py_stringify(PyObject
*py_obj
)
28 PyObject
*py_str
, *py_bytes
;
31 /* Note: Caller already ran PyGILState_Ensure(). */
36 py_str
= PyObject_Str(py_obj
);
37 if (!py_str
|| !PyUnicode_Check(py_str
))
40 py_bytes
= PyUnicode_AsUTF8String(py_str
);
44 str
= g_strdup(PyBytes_AsString(py_bytes
));
51 srd_dbg("Failed to stringify object.");
57 static char *py_get_string_attr(PyObject
*py_obj
, const char *attr
)
59 PyObject
*py_str
, *py_bytes
;
62 /* Note: Caller already ran PyGILState_Ensure(). */
67 py_str
= PyObject_GetAttrString(py_obj
, attr
);
68 if (!py_str
|| !PyUnicode_Check(py_str
))
71 py_bytes
= PyUnicode_AsUTF8String(py_str
);
75 str
= g_strdup(PyBytes_AsString(py_bytes
));
82 srd_dbg("Failed to get object attribute %s.", attr
);
89 SRD_PRIV
void srd_exception_catch(const char *format
, ...)
93 PyObject
*py_etype
, *py_evalue
, *py_etraceback
;
94 PyObject
*py_mod
, *py_func
, *py_tracefmt
;
95 char *msg
, *etype_name
, *evalue_str
, *outstr
;
96 const char *etype_name_fallback
;
97 PyGILState_STATE gstate
;
100 py_etype
= py_evalue
= py_etraceback
= py_mod
= py_func
= NULL
;
102 va_start(args
, format
);
103 msg
= g_strdup_vprintf(format
, args
);
106 gstate
= PyGILState_Ensure();
108 PyErr_Fetch(&py_etype
, &py_evalue
, &py_etraceback
);
110 /* No current exception, so just print the message. */
114 PyErr_NormalizeException(&py_etype
, &py_evalue
, &py_etraceback
);
116 etype_name
= py_get_string_attr(py_etype
, "__name__");
117 evalue_str
= py_stringify(py_evalue
);
118 etype_name_fallback
= (etype_name
) ? etype_name
: "(unknown exception)";
121 srd_err("%s: %s: %s", etype_name_fallback
, msg
, evalue_str
);
123 srd_err("%s: %s.", etype_name_fallback
, msg
);
128 /* If there is no traceback object, we are done. */
132 py_mod
= py_import_by_name("traceback");
136 py_func
= PyObject_GetAttrString(py_mod
, "format_exception");
137 if (!py_func
|| !PyCallable_Check(py_func
))
140 /* Call into Python to format the stack trace. */
141 py_tracefmt
= PyObject_CallFunctionObjArgs(py_func
,
142 py_etype
, py_evalue
, py_etraceback
, NULL
);
143 if (!py_tracefmt
|| !PyList_Check(py_tracefmt
))
146 s
= g_string_sized_new(128);
147 for (i
= 0; i
< PyList_Size(py_tracefmt
); i
++) {
148 ret
= py_listitem_as_str(py_tracefmt
, i
, &outstr
);
150 s
= g_string_append(s
, outstr
);
154 srd_err("%s", s
->str
);
155 g_string_free(s
, TRUE
);
157 Py_DECREF(py_tracefmt
);
162 Py_XDECREF(py_etraceback
);
163 Py_XDECREF(py_evalue
);
164 Py_XDECREF(py_etype
);
169 PyGILState_Release(gstate
);