summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBert Vermeulen <bert@biot.com>2012-01-23 02:20:51 +0100
committerBert Vermeulen <bert@biot.com>2012-01-23 04:53:32 +0100
commitec871a279893cfe0ab378eddc0a9f9bcccc44925 (patch)
tree46255d4312c2c059d28f6927ec5d07e744163228
parent4fadb1282f5e9aa41abcb67e7d90cdc4a9b2628d (diff)
downloadlibsigrokdecode-ec871a279893cfe0ab378eddc0a9f9bcccc44925.tar.gz
libsigrokdecode-ec871a279893cfe0ab378eddc0a9f9bcccc44925.zip
srd: add python exception catcher, which routes to srd_err() and srd_dbg()
-rw-r--r--Makefile.am2
-rw-r--r--exception.c95
-rw-r--r--sigrokdecode.h3
3 files changed, 99 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index d7e33c2..fd5e004 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -24,7 +24,7 @@ SUBDIRS = decoders
lib_LTLIBRARIES = libsigrokdecode.la
-libsigrokdecode_la_SOURCES = controller.c decoder.c log.c util.c \
+libsigrokdecode_la_SOURCES = controller.c decoder.c log.c util.c exception.c \
module_sigrokdecode.c type_decoder.c type_logic.c
libsigrokdecode_la_CPPFLAGS = $(CPPFLAGS_PYTHON) \
diff --git a/exception.c b/exception.c
new file mode 100644
index 0000000..07ffab3
--- /dev/null
+++ b/exception.c
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the sigrok project.
+ *
+ * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "sigrokdecode.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
+#include "sigrokdecode-internal.h"
+#include "config.h"
+#include <stdarg.h>
+#include <glib.h>
+#include <frameobject.h> /* Python header not pulled in by default. */
+
+
+void catch_exception(const char *format, ...)
+{
+ PyObject *etype, *evalue, *etb, *py_str;
+ PyTracebackObject *py_tb;
+ GString *msg;
+ va_list args;
+ char *ename, *str, *tracestr;
+
+ if (!PyErr_Occurred())
+ /* Nothing is wrong. */
+ return;
+
+ PyErr_Fetch(&etype, &evalue, &etb);
+ PyErr_NormalizeException(&etype, &evalue, &etb);
+
+ if (!(py_str = PyObject_Str(evalue))) {
+ /* Shouldn't happen */
+ srd_dbg("srd: failed to convert exception value to string");
+ return;
+ }
+
+ msg = g_string_sized_new(128);
+ va_start(args, format);
+ g_string_vprintf(msg, format, args);
+ va_end(args);
+
+ /* Can be NULL. */
+ if (evalue)
+ ename = (char *)Py_TYPE(evalue)->tp_name;
+ else
+ ename = "(unknown exception)";
+
+ /* Send the exception error message(s) to srd_err(). */
+ py_str_as_str(py_str, &str);
+ g_string_append(msg, ename);
+ g_string_append(msg, ": ");
+ g_string_append(msg, str);
+ Py_DecRef(py_str);
+ srd_err(msg->str);
+
+ /* Send a more precise error location to srd_dbg(), if we have it. */
+ if (etb && etb != Py_None) {
+ tracestr = NULL;
+ py_tb = (PyTracebackObject *) etb;
+ py_str = PyUnicode_FromFormat("%U:%d in %U",
+ py_tb->tb_frame->f_code->co_filename, py_tb->tb_frame->f_lineno,
+ py_tb->tb_frame->f_code->co_name);
+ py_str_as_str(py_str, &tracestr);
+ Py_DecRef(py_str);
+ g_string_printf(msg, "srd: %s in %s: %s", ename,
+ tracestr, str);
+ srd_dbg(msg->str);
+ g_free(tracestr);
+ }
+ g_free(str);
+ g_string_free(msg, TRUE);
+
+ Py_XDECREF(etype);
+ Py_XDECREF(evalue);
+ Py_XDECREF(etb);
+
+ /* Just in case. */
+ PyErr_Clear();
+
+ return;
+}
+
+
diff --git a/sigrokdecode.h b/sigrokdecode.h
index 70652a4..dfddb13 100644
--- a/sigrokdecode.h
+++ b/sigrokdecode.h
@@ -206,6 +206,9 @@ int srd_load_all_decoders(void);
int srd_unload_all_decoders(void);
char *srd_decoder_doc(struct srd_decoder *dec);
+/*--- exception.c -----------------------------------------------------------*/
+void catch_exception(const char *format, ...);
+
/*--- util.c ----------------------------------------------------------------*/
int py_attr_as_str(PyObject *py_obj, const char *attr, char **outstr);
int py_dictitem_as_str(PyObject *py_obj, const char *key, char **outstr);