157 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			157 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * QError Module
 | |
|  *
 | |
|  * Copyright (C) 2009 Red Hat Inc.
 | |
|  *
 | |
|  * Authors:
 | |
|  *  Luiz Capitulino <lcapitulino@redhat.com>
 | |
|  *
 | |
|  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
 | |
|  * See the COPYING.LIB file in the top-level directory.
 | |
|  */
 | |
| 
 | |
| #include "monitor.h"
 | |
| #include "qjson.h"
 | |
| #include "qerror.h"
 | |
| #include "qemu-common.h"
 | |
| 
 | |
| static void qerror_destroy_obj(QObject *obj);
 | |
| 
 | |
| static const QType qerror_type = {
 | |
|     .code = QTYPE_QERROR,
 | |
|     .destroy = qerror_destroy_obj,
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * qerror_new(): Create a new QError
 | |
|  *
 | |
|  * Return strong reference.
 | |
|  */
 | |
| static QError *qerror_new(void)
 | |
| {
 | |
|     QError *qerr;
 | |
| 
 | |
|     qerr = g_malloc0(sizeof(*qerr));
 | |
|     QOBJECT_INIT(qerr, &qerror_type);
 | |
| 
 | |
|     return qerr;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * qerror_from_info(): Create a new QError from error information
 | |
|  *
 | |
|  * Return strong reference.
 | |
|  */
 | |
| static QError *qerror_from_info(ErrorClass err_class, const char *fmt,
 | |
|                                 va_list *va)
 | |
| {
 | |
|     QError *qerr;
 | |
| 
 | |
|     qerr = qerror_new();
 | |
|     loc_save(&qerr->loc);
 | |
| 
 | |
|     qerr->err_msg = g_strdup_vprintf(fmt, *va);
 | |
|     qerr->err_class = err_class;
 | |
| 
 | |
|     return qerr;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * qerror_human(): Format QError data into human-readable string.
 | |
|  */
 | |
| QString *qerror_human(const QError *qerror)
 | |
| {
 | |
|     return qstring_from_str(qerror->err_msg);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * qerror_print(): Print QError data
 | |
|  *
 | |
|  * This function will print the member 'desc' of the specified QError object,
 | |
|  * it uses error_report() for this, so that the output is routed to the right
 | |
|  * place (ie. stderr or Monitor's device).
 | |
|  */
 | |
| static void qerror_print(QError *qerror)
 | |
| {
 | |
|     QString *qstring = qerror_human(qerror);
 | |
|     loc_push_restore(&qerror->loc);
 | |
|     error_report("%s", qstring_get_str(qstring));
 | |
|     loc_pop(&qerror->loc);
 | |
|     QDECREF(qstring);
 | |
| }
 | |
| 
 | |
| void qerror_report(ErrorClass eclass, const char *fmt, ...)
 | |
| {
 | |
|     va_list va;
 | |
|     QError *qerror;
 | |
| 
 | |
|     va_start(va, fmt);
 | |
|     qerror = qerror_from_info(eclass, fmt, &va);
 | |
|     va_end(va);
 | |
| 
 | |
|     if (monitor_cur_is_qmp()) {
 | |
|         monitor_set_error(cur_mon, qerror);
 | |
|     } else {
 | |
|         qerror_print(qerror);
 | |
|         QDECREF(qerror);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* Evil... */
 | |
| struct Error
 | |
| {
 | |
|     char *msg;
 | |
|     ErrorClass err_class;
 | |
| };
 | |
| 
 | |
| void qerror_report_err(Error *err)
 | |
| {
 | |
|     QError *qerr;
 | |
| 
 | |
|     qerr = qerror_new();
 | |
|     loc_save(&qerr->loc);
 | |
|     qerr->err_msg = g_strdup(err->msg);
 | |
|     qerr->err_class = err->err_class;
 | |
| 
 | |
|     if (monitor_cur_is_qmp()) {
 | |
|         monitor_set_error(cur_mon, qerr);
 | |
|     } else {
 | |
|         qerror_print(qerr);
 | |
|         QDECREF(qerr);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void assert_no_error(Error *err)
 | |
| {
 | |
|     if (err) {
 | |
|         qerror_report_err(err);
 | |
|         abort();
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * qobject_to_qerror(): Convert a QObject into a QError
 | |
|  */
 | |
| static QError *qobject_to_qerror(const QObject *obj)
 | |
| {
 | |
|     if (qobject_type(obj) != QTYPE_QERROR) {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     return container_of(obj, QError, base);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * qerror_destroy_obj(): Free all memory allocated by a QError
 | |
|  */
 | |
| static void qerror_destroy_obj(QObject *obj)
 | |
| {
 | |
|     QError *qerr;
 | |
| 
 | |
|     assert(obj != NULL);
 | |
|     qerr = qobject_to_qerror(obj);
 | |
| 
 | |
|     g_free(qerr->err_msg);
 | |
|     g_free(qerr);
 | |
| }
 |