On Fri, Mar 11, 2011 at 11:00 PM, Anthony Liguori <aligu...@us.ibm.com> wrote: > The Error class is similar to QError (now deprecated) except that it supports > propagation. This allows for higher quality error handling. It's losely > modeled after glib style GErrors. > > Signed-off-by: Anthony Liguori <aligu...@us.ibm.com> > > diff --git a/Makefile.objs b/Makefile.objs > index 0ba02c7..da31530 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -15,6 +15,7 @@ oslib-obj-$(CONFIG_POSIX) += oslib-posix.o > > block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o > block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o > +block-obj-y += error.o > block-obj-$(CONFIG_POSIX) += posix-aio-compat.o > block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o > > diff --git a/error.c b/error.c > new file mode 100644 > index 0000000..5d84106 > --- /dev/null > +++ b/error.c > @@ -0,0 +1,122 @@ > +/* > + * QEMU Error Objects > + * > + * Copyright IBM, Corp. 2011 > + * > + * Authors: > + * Anthony Liguori <aligu...@us.ibm.com> > + * > + * This work is licensed under the terms of the GNU LGPL, version 2. See > + * the COPYING.LIB file in the top-level directory. > + */ > +#include "error.h" > +#include "error_int.h" > +#include "qemu-objects.h" > +#include "qerror.h" > +#include <assert.h> > + > +struct Error > +{ > + QDict *obj; > + const char *fmt; > + char *msg; > +}; > + > +void error_set(Error **errp, const char *fmt, ...) > +{ > + Error *err; > + va_list ap; > + > + if (errp == NULL) { > + return; > + } > + > + err = qemu_mallocz(sizeof(*err)); > + > + va_start(ap, fmt); > + err->obj = qobject_to_qdict(qobject_from_jsonv(fmt, &ap)); > + va_end(ap); > + err->fmt = fmt; > + > + *errp = err; > +} > + > +bool error_is_set(Error **errp) > +{ > + return (errp && *errp); > +} > + > +const char *error_get_pretty(Error *err) > +{ > + if (err->msg == NULL) { > + QString *str; > + str = qerror_format(err->fmt, err->obj); > + err->msg = qemu_strdup(qstring_get_str(str)); > + } > + > + return err->msg; > +} > + > +const char *error_get_field(Error *err, const char *field) > +{ > + if (strcmp(field, "class") == 0) { > + return qdict_get_str(err->obj, field); > + } else { > + QDict *dict = qdict_get_qdict(err->obj, "data"); > + return qdict_get_str(dict, field); > + } > +} > + > +void error_free(Error *err) > +{ > + QDECREF(err->obj); > + qemu_free(err->msg); > + qemu_free(err); > +} > + > +bool error_is_type(Error *err, const char *fmt) > +{ > + char *ptr; > + char *end; > + char classname[1024]; > + > + ptr = strstr(fmt, "'class': '"); > + assert(ptr != NULL); > + ptr += strlen("'class': '"); > + > + end = strchr(ptr, '\''); > + assert(end != NULL); > + > + memcpy(classname, ptr, (end - ptr)); > + classname[(end - ptr)] = 0; > + > + return strcmp(classname, error_get_field(err, "class")) == 0; > +} > + > +void error_propagate(Error **dst_err, Error *local_err) > +{ > + if (dst_err) { > + *dst_err = local_err; > + } else if (local_err) { > + error_free(local_err); > + } > +} > + > +QObject *error_get_qobject(Error *err) > +{ > + QINCREF(err->obj); > + return QOBJECT(err->obj); > +} > + > +void error_set_qobject(Error **errp, QObject *obj) > +{ > + Error *err; > + if (errp == NULL) { > + return; > + } > + err = qemu_mallocz(sizeof(*err)); > + err->obj = qobject_to_qdict(obj); > + qobject_incref(obj); > + > + *errp = err; > +} > diff --git a/error.h b/error.h > new file mode 100644
The name is too generic, it could conflict with system headers. At least I have /usr/include/error.h. > index 0000000..317d487 > --- /dev/null > +++ b/error.h > @@ -0,0 +1,65 @@ > +/* > + * QEMU Error Objects > + * > + * Copyright IBM, Corp. 2011 > + * > + * Authors: > + * Anthony Liguori <aligu...@us.ibm.com> > + * > + * This work is licensed under the terms of the GNU LGPL, version 2. See > + * the COPYING.LIB file in the top-level directory. > + */ > +#ifndef ERROR_H > +#define ERROR_H This #define could also conflict with system headers. In my system, _ERROR_H is used, but who knows all error.h files out there?