X-Git-Url: http://sigrok.org/gitweb/?p=libsigrokdecode.git;a=blobdiff_plain;f=exception.c;fp=exception.c;h=07ffab35969770851f941cc0d1bd0a8effac81f1;hp=0000000000000000000000000000000000000000;hb=ec871a279893cfe0ab378eddc0a9f9bcccc44925;hpb=4fadb1282f5e9aa41abcb67e7d90cdc4a9b2628d 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 + * + * 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 . + */ + +#include "sigrokdecode.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */ +#include "sigrokdecode-internal.h" +#include "config.h" +#include +#include +#include /* 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; +} + +