summaryrefslogtreecommitdiffstats
path: root/qemu/include/qapi
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/include/qapi')
-rw-r--r--qemu/include/qapi/error.h312
-rw-r--r--qemu/include/qapi/qmp-event.h1
-rw-r--r--qemu/include/qapi/qmp/dispatch.h1
-rw-r--r--qemu/include/qapi/qmp/json-lexer.h15
-rw-r--r--qemu/include/qapi/qmp/json-parser.h5
-rw-r--r--qemu/include/qapi/qmp/json-streamer.h14
-rw-r--r--qemu/include/qapi/qmp/qbool.h4
-rw-r--r--qemu/include/qapi/qmp/qdict.h5
-rw-r--r--qemu/include/qapi/qmp/qerror.h6
-rw-r--r--qemu/include/qapi/qmp/qfloat.h4
-rw-r--r--qemu/include/qapi/qmp/qint.h4
-rw-r--r--qemu/include/qapi/qmp/qjson.h2
-rw-r--r--qemu/include/qapi/qmp/qlist.h3
-rw-r--r--qemu/include/qapi/qmp/qobject.h57
-rw-r--r--qemu/include/qapi/qmp/qstring.h4
-rw-r--r--qemu/include/qapi/visitor-impl.h75
-rw-r--r--qemu/include/qapi/visitor.h123
17 files changed, 431 insertions, 204 deletions
diff --git a/qemu/include/qapi/error.h b/qemu/include/qapi/error.h
index f44c45183..11be2327c 100644
--- a/qemu/include/qapi/error.h
+++ b/qemu/include/qapi/error.h
@@ -2,107 +2,301 @@
* QEMU Error Objects
*
* Copyright IBM, Corp. 2011
+ * Copyright (C) 2011-2015 Red Hat, Inc.
*
* Authors:
* Anthony Liguori <aliguori@us.ibm.com>
+ * Markus Armbruster <armbru@redhat.com>
*
* This work is licensed under the terms of the GNU LGPL, version 2. See
* the COPYING.LIB file in the top-level directory.
*/
+
+/*
+ * Error reporting system loosely patterned after Glib's GError.
+ *
+ * Create an error:
+ * error_setg(&err, "situation normal, all fouled up");
+ *
+ * Create an error and add additional explanation:
+ * error_setg(&err, "invalid quark");
+ * error_append_hint(&err, "Valid quarks are up, down, strange, "
+ * "charm, top, bottom.\n");
+ *
+ * Do *not* contract this to
+ * error_setg(&err, "invalid quark\n"
+ * "Valid quarks are up, down, strange, charm, top, bottom.");
+ *
+ * Report an error to the current monitor if we have one, else stderr:
+ * error_report_err(err);
+ * This frees the error object.
+ *
+ * Likewise, but with additional text prepended:
+ * error_reportf_err(err, "Could not frobnicate '%s': ", name);
+ *
+ * Report an error somewhere else:
+ * const char *msg = error_get_pretty(err);
+ * do with msg what needs to be done...
+ * error_free(err);
+ * Note that this loses hints added with error_append_hint().
+ *
+ * Handle an error without reporting it (just for completeness):
+ * error_free(err);
+ *
+ * Assert that an expected error occurred, but clean it up without
+ * reporting it (primarily useful in testsuites):
+ * error_free_or_abort(&err);
+ *
+ * Pass an existing error to the caller:
+ * error_propagate(errp, err);
+ * where Error **errp is a parameter, by convention the last one.
+ *
+ * Pass an existing error to the caller with the message modified:
+ * error_propagate(errp, err);
+ * error_prepend(errp, "Could not frobnicate '%s': ", name);
+ *
+ * Create a new error and pass it to the caller:
+ * error_setg(errp, "situation normal, all fouled up");
+ *
+ * Call a function and receive an error from it:
+ * Error *err = NULL;
+ * foo(arg, &err);
+ * if (err) {
+ * handle the error...
+ * }
+ *
+ * Call a function ignoring errors:
+ * foo(arg, NULL);
+ *
+ * Call a function aborting on errors:
+ * foo(arg, &error_abort);
+ *
+ * Call a function treating errors as fatal:
+ * foo(arg, &error_fatal);
+ *
+ * Receive an error and pass it on to the caller:
+ * Error *err = NULL;
+ * foo(arg, &err);
+ * if (err) {
+ * handle the error...
+ * error_propagate(errp, err);
+ * }
+ * where Error **errp is a parameter, by convention the last one.
+ *
+ * Do *not* "optimize" this to
+ * foo(arg, errp);
+ * if (*errp) { // WRONG!
+ * handle the error...
+ * }
+ * because errp may be NULL!
+ *
+ * But when all you do with the error is pass it on, please use
+ * foo(arg, errp);
+ * for readability.
+ *
+ * Receive and accumulate multiple errors (first one wins):
+ * Error *err = NULL, *local_err = NULL;
+ * foo(arg, &err);
+ * bar(arg, &local_err);
+ * error_propagate(&err, local_err);
+ * if (err) {
+ * handle the error...
+ * }
+ *
+ * Do *not* "optimize" this to
+ * foo(arg, &err);
+ * bar(arg, &err); // WRONG!
+ * if (err) {
+ * handle the error...
+ * }
+ * because this may pass a non-null err to bar().
+ */
+
#ifndef ERROR_H
#define ERROR_H
-#include "qemu/compiler.h"
#include "qapi-types.h"
-#include <stdbool.h>
-/**
- * A class representing internal errors within QEMU. An error has a ErrorClass
- * code and a human message.
+/*
+ * Overall category of an error.
+ * Based on the qapi type QapiErrorClass, but reproduced here for nicer
+ * enum names.
*/
-typedef struct Error Error;
+typedef enum ErrorClass {
+ ERROR_CLASS_GENERIC_ERROR = QAPI_ERROR_CLASS_GENERICERROR,
+ ERROR_CLASS_COMMAND_NOT_FOUND = QAPI_ERROR_CLASS_COMMANDNOTFOUND,
+ ERROR_CLASS_DEVICE_ENCRYPTED = QAPI_ERROR_CLASS_DEVICEENCRYPTED,
+ ERROR_CLASS_DEVICE_NOT_ACTIVE = QAPI_ERROR_CLASS_DEVICENOTACTIVE,
+ ERROR_CLASS_DEVICE_NOT_FOUND = QAPI_ERROR_CLASS_DEVICENOTFOUND,
+ ERROR_CLASS_KVM_MISSING_CAP = QAPI_ERROR_CLASS_KVMMISSINGCAP,
+} ErrorClass;
-/**
- * Set an indirect pointer to an error given a ErrorClass value and a
- * printf-style human message. This function is not meant to be used outside
- * of QEMU.
+/*
+ * Get @err's human-readable error message.
*/
-void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
- GCC_FMT_ATTR(3, 4);
+const char *error_get_pretty(Error *err);
-/**
- * Set an indirect pointer to an error given a ErrorClass value and a
- * printf-style human message, followed by a strerror() string if
- * @os_error is not zero.
+/*
+ * Get @err's error class.
+ * Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is
+ * strongly discouraged.
*/
-void error_set_errno(Error **errp, int os_error, ErrorClass err_class,
- const char *fmt, ...) GCC_FMT_ATTR(4, 5);
+ErrorClass error_get_class(const Error *err);
-#ifdef _WIN32
-/**
- * Set an indirect pointer to an error given a ErrorClass value and a
- * printf-style human message, followed by a g_win32_error_message() string if
- * @win32_err is not zero.
+/*
+ * Create a new error object and assign it to *@errp.
+ * If @errp is NULL, the error is ignored. Don't bother creating one
+ * then.
+ * If @errp is &error_abort, print a suitable message and abort().
+ * If @errp is &error_fatal, print a suitable message and exit(1).
+ * If @errp is anything else, *@errp must be NULL.
+ * The new error's class is ERROR_CLASS_GENERIC_ERROR, and its
+ * human-readable error message is made from printf-style @fmt, ...
+ * The resulting message should be a single phrase, with no newline or
+ * trailing punctuation.
+ * Please don't error_setg(&error_fatal, ...), use error_report() and
+ * exit(), because that's more obvious.
+ * Likewise, don't error_setg(&error_abort, ...), use assert().
*/
-void error_set_win32(Error **errp, int win32_err, ErrorClass err_class,
- const char *fmt, ...) GCC_FMT_ATTR(4, 5);
-#endif
+#define error_setg(errp, fmt, ...) \
+ error_setg_internal((errp), __FILE__, __LINE__, __func__, \
+ (fmt), ## __VA_ARGS__)
+void error_setg_internal(Error **errp,
+ const char *src, int line, const char *func,
+ const char *fmt, ...)
+ GCC_FMT_ATTR(5, 6);
-/**
- * Same as error_set(), but sets a generic error
+/*
+ * Just like error_setg(), with @os_error info added to the message.
+ * If @os_error is non-zero, ": " + strerror(os_error) is appended to
+ * the human-readable error message.
*/
-#define error_setg(errp, fmt, ...) \
- error_set(errp, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
-#define error_setg_errno(errp, os_error, fmt, ...) \
- error_set_errno(errp, os_error, ERROR_CLASS_GENERIC_ERROR, \
- fmt, ## __VA_ARGS__)
+#define error_setg_errno(errp, os_error, fmt, ...) \
+ error_setg_errno_internal((errp), __FILE__, __LINE__, __func__, \
+ (os_error), (fmt), ## __VA_ARGS__)
+void error_setg_errno_internal(Error **errp,
+ const char *fname, int line, const char *func,
+ int os_error, const char *fmt, ...)
+ GCC_FMT_ATTR(6, 7);
+
#ifdef _WIN32
-#define error_setg_win32(errp, win32_err, fmt, ...) \
- error_set_win32(errp, win32_err, ERROR_CLASS_GENERIC_ERROR, \
- fmt, ## __VA_ARGS__)
+/*
+ * Just like error_setg(), with @win32_error info added to the message.
+ * If @win32_error is non-zero, ": " + g_win32_error_message(win32_err)
+ * is appended to the human-readable error message.
+ */
+#define error_setg_win32(errp, win32_err, fmt, ...) \
+ error_setg_win32_internal((errp), __FILE__, __LINE__, __func__, \
+ (win32_err), (fmt), ## __VA_ARGS__)
+void error_setg_win32_internal(Error **errp,
+ const char *src, int line, const char *func,
+ int win32_err, const char *fmt, ...)
+ GCC_FMT_ATTR(6, 7);
#endif
-/**
- * Helper for open() errors
+/*
+ * Propagate error object (if any) from @local_err to @dst_errp.
+ * If @local_err is NULL, do nothing (because there's nothing to
+ * propagate).
+ * Else, if @dst_errp is NULL, errors are being ignored. Free the
+ * error object.
+ * Else, if @dst_errp is &error_abort, print a suitable message and
+ * abort().
+ * Else, if @dst_errp is &error_fatal, print a suitable message and
+ * exit(1).
+ * Else, if @dst_errp already contains an error, ignore this one: free
+ * the error object.
+ * Else, move the error object from @local_err to *@dst_errp.
+ * On return, @local_err is invalid.
+ * Please don't error_propagate(&error_fatal, ...), use
+ * error_report_err() and exit(), because that's more obvious.
*/
-void error_setg_file_open(Error **errp, int os_errno, const char *filename);
+void error_propagate(Error **dst_errp, Error *local_err);
/*
- * Get the error class of an error object.
+ * Prepend some text to @errp's human-readable error message.
+ * The text is made by formatting @fmt, @ap like vprintf().
*/
-ErrorClass error_get_class(const Error *err);
+void error_vprepend(Error **errp, const char *fmt, va_list ap);
-/**
- * Returns an exact copy of the error passed as an argument.
+/*
+ * Prepend some text to @errp's human-readable error message.
+ * The text is made by formatting @fmt, ... like printf().
*/
-Error *error_copy(const Error *err);
+void error_prepend(Error **errp, const char *fmt, ...)
+ GCC_FMT_ATTR(2, 3);
-/**
- * Get a human readable representation of an error object.
+/*
+ * Append a printf-style human-readable explanation to an existing error.
+ * @errp may be NULL, but not &error_fatal or &error_abort.
+ * Trivially the case if you call it only after error_setg() or
+ * error_propagate().
+ * May be called multiple times. The resulting hint should end with a
+ * newline.
*/
-const char *error_get_pretty(Error *err);
+void error_append_hint(Error **errp, const char *fmt, ...)
+ GCC_FMT_ATTR(2, 3);
-/**
- * Convenience function to error_report() and free an error object.
+/*
+ * Convenience function to report open() failure.
*/
-void error_report_err(Error *);
+#define error_setg_file_open(errp, os_errno, filename) \
+ error_setg_file_open_internal((errp), __FILE__, __LINE__, __func__, \
+ (os_errno), (filename))
+void error_setg_file_open_internal(Error **errp,
+ const char *src, int line, const char *func,
+ int os_errno, const char *filename);
-/**
- * Propagate an error to an indirect pointer to an error. This function will
- * always transfer ownership of the error reference and handles the case where
- * dst_err is NULL correctly. Errors after the first are discarded.
+/*
+ * Return an exact copy of @err.
*/
-void error_propagate(Error **dst_errp, Error *local_err);
+Error *error_copy(const Error *err);
-/**
- * Free an error object.
+/*
+ * Free @err.
+ * @err may be NULL.
*/
void error_free(Error *err);
-/**
- * If passed to error_set and friends, abort().
+/*
+ * Convenience function to assert that *@errp is set, then silently free it.
+ */
+void error_free_or_abort(Error **errp);
+
+/*
+ * Convenience function to error_report() and free @err.
*/
+void error_report_err(Error *err);
+/*
+ * Convenience function to error_prepend(), error_report() and free @err.
+ */
+void error_reportf_err(Error *err, const char *fmt, ...)
+ GCC_FMT_ATTR(2, 3);
+
+/*
+ * Just like error_setg(), except you get to specify the error class.
+ * Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is
+ * strongly discouraged.
+ */
+#define error_set(errp, err_class, fmt, ...) \
+ error_set_internal((errp), __FILE__, __LINE__, __func__, \
+ (err_class), (fmt), ## __VA_ARGS__)
+void error_set_internal(Error **errp,
+ const char *src, int line, const char *func,
+ ErrorClass err_class, const char *fmt, ...)
+ GCC_FMT_ATTR(6, 7);
+
+/*
+ * Special error destination to abort on error.
+ * See error_setg() and error_propagate() for details.
+ */
extern Error *error_abort;
+/*
+ * Special error destination to exit(1) on error.
+ * See error_setg() and error_propagate() for details.
+ */
+extern Error *error_fatal;
+
#endif
diff --git a/qemu/include/qapi/qmp-event.h b/qemu/include/qapi/qmp-event.h
index 8a8ffb571..40fe3cbc1 100644
--- a/qemu/include/qapi/qmp-event.h
+++ b/qemu/include/qapi/qmp-event.h
@@ -14,7 +14,6 @@
#ifndef QMP_EVENT_H
#define QMP_EVENT_H
-#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict, Error **errp);
diff --git a/qemu/include/qapi/qmp/dispatch.h b/qemu/include/qapi/qmp/dispatch.h
index e389697f1..495520994 100644
--- a/qemu/include/qapi/qmp/dispatch.h
+++ b/qemu/include/qapi/qmp/dispatch.h
@@ -16,7 +16,6 @@
#include "qapi/qmp/qobject.h"
#include "qapi/qmp/qdict.h"
-#include "qapi/error.h"
typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
diff --git a/qemu/include/qapi/qmp/json-lexer.h b/qemu/include/qapi/qmp/json-lexer.h
index cdff0460a..afee7828c 100644
--- a/qemu/include/qapi/qmp/json-lexer.h
+++ b/qemu/include/qapi/qmp/json-lexer.h
@@ -14,11 +14,15 @@
#ifndef QEMU_JSON_LEXER_H
#define QEMU_JSON_LEXER_H
-#include "qapi/qmp/qstring.h"
-#include "qapi/qmp/qlist.h"
typedef enum json_token_type {
- JSON_OPERATOR = 100,
+ JSON_MIN = 100,
+ JSON_LCURLY = JSON_MIN,
+ JSON_RCURLY,
+ JSON_LSQUARE,
+ JSON_RSQUARE,
+ JSON_COLON,
+ JSON_COMMA,
JSON_INTEGER,
JSON_FLOAT,
JSON_KEYWORD,
@@ -30,13 +34,14 @@ typedef enum json_token_type {
typedef struct JSONLexer JSONLexer;
-typedef void (JSONLexerEmitter)(JSONLexer *, QString *, JSONTokenType, int x, int y);
+typedef void (JSONLexerEmitter)(JSONLexer *, GString *,
+ JSONTokenType, int x, int y);
struct JSONLexer
{
JSONLexerEmitter *emit;
int state;
- QString *token;
+ GString *token;
int x, y;
};
diff --git a/qemu/include/qapi/qmp/json-parser.h b/qemu/include/qapi/qmp/json-parser.h
index 44d88f346..9987f8ca8 100644
--- a/qemu/include/qapi/qmp/json-parser.h
+++ b/qemu/include/qapi/qmp/json-parser.h
@@ -16,9 +16,8 @@
#include "qemu-common.h"
#include "qapi/qmp/qlist.h"
-#include "qapi/error.h"
-QObject *json_parser_parse(QList *tokens, va_list *ap);
-QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp);
+QObject *json_parser_parse(GQueue *tokens, va_list *ap);
+QObject *json_parser_parse_err(GQueue *tokens, va_list *ap, Error **errp);
#endif
diff --git a/qemu/include/qapi/qmp/json-streamer.h b/qemu/include/qapi/qmp/json-streamer.h
index 823f7d7fa..00d8a23af 100644
--- a/qemu/include/qapi/qmp/json-streamer.h
+++ b/qemu/include/qapi/qmp/json-streamer.h
@@ -14,21 +14,27 @@
#ifndef QEMU_JSON_STREAMER_H
#define QEMU_JSON_STREAMER_H
-#include "qapi/qmp/qlist.h"
#include "qapi/qmp/json-lexer.h"
+typedef struct JSONToken {
+ int type;
+ int x;
+ int y;
+ char str[];
+} JSONToken;
+
typedef struct JSONMessageParser
{
- void (*emit)(struct JSONMessageParser *parser, QList *tokens);
+ void (*emit)(struct JSONMessageParser *parser, GQueue *tokens);
JSONLexer lexer;
int brace_count;
int bracket_count;
- QList *tokens;
+ GQueue *tokens;
uint64_t token_size;
} JSONMessageParser;
void json_message_parser_init(JSONMessageParser *parser,
- void (*func)(JSONMessageParser *, QList *));
+ void (*func)(JSONMessageParser *, GQueue *));
int json_message_parser_feed(JSONMessageParser *parser,
const char *buffer, size_t size);
diff --git a/qemu/include/qapi/qmp/qbool.h b/qemu/include/qapi/qmp/qbool.h
index 4aa6be3b3..a41111c30 100644
--- a/qemu/include/qapi/qmp/qbool.h
+++ b/qemu/include/qapi/qmp/qbool.h
@@ -14,16 +14,16 @@
#ifndef QBOOL_H
#define QBOOL_H
-#include <stdbool.h>
#include "qapi/qmp/qobject.h"
typedef struct QBool {
- QObject_HEAD;
+ QObject base;
bool value;
} QBool;
QBool *qbool_from_bool(bool value);
bool qbool_get_bool(const QBool *qb);
QBool *qobject_to_qbool(const QObject *obj);
+void qbool_destroy_obj(QObject *obj);
#endif /* QBOOL_H */
diff --git a/qemu/include/qapi/qmp/qdict.h b/qemu/include/qapi/qmp/qdict.h
index a37f4c156..71b8eb041 100644
--- a/qemu/include/qapi/qmp/qdict.h
+++ b/qemu/include/qapi/qmp/qdict.h
@@ -16,8 +16,6 @@
#include "qapi/qmp/qobject.h"
#include "qapi/qmp/qlist.h"
#include "qemu/queue.h"
-#include <stdbool.h>
-#include <stdint.h>
#define QDICT_BUCKET_MAX 512
@@ -28,7 +26,7 @@ typedef struct QDictEntry {
} QDictEntry;
typedef struct QDict {
- QObject_HEAD;
+ QObject base;
size_t size;
QLIST_HEAD(,QDictEntry) table[QDICT_BUCKET_MAX];
} QDict;
@@ -48,6 +46,7 @@ void qdict_iter(const QDict *qdict,
void *opaque);
const QDictEntry *qdict_first(const QDict *qdict);
const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry);
+void qdict_destroy_obj(QObject *obj);
/* Helper to qdict_put_obj(), accepts any object */
#define qdict_put(qdict, key, obj) \
diff --git a/qemu/include/qapi/qmp/qerror.h b/qemu/include/qapi/qmp/qerror.h
index 842b27ae1..d08652aaa 100644
--- a/qemu/include/qapi/qmp/qerror.h
+++ b/qemu/include/qapi/qmp/qerror.h
@@ -100,10 +100,10 @@
#define QERR_UNDEFINED_ERROR \
"An undefined error has occurred"
-#define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \
- "'%s' uses a %s feature which is not supported by this qemu version: %s"
-
#define QERR_UNSUPPORTED \
"this feature or command is not currently supported"
+#define QERR_REPLAY_NOT_SUPPORTED \
+ "Record/replay feature is not supported for '%s'"
+
#endif /* QERROR_H */
diff --git a/qemu/include/qapi/qmp/qfloat.h b/qemu/include/qapi/qmp/qfloat.h
index a8658443d..b5d15836b 100644
--- a/qemu/include/qapi/qmp/qfloat.h
+++ b/qemu/include/qapi/qmp/qfloat.h
@@ -14,16 +14,16 @@
#ifndef QFLOAT_H
#define QFLOAT_H
-#include <stdint.h>
#include "qapi/qmp/qobject.h"
typedef struct QFloat {
- QObject_HEAD;
+ QObject base;
double value;
} QFloat;
QFloat *qfloat_from_double(double value);
double qfloat_get_double(const QFloat *qi);
QFloat *qobject_to_qfloat(const QObject *obj);
+void qfloat_destroy_obj(QObject *obj);
#endif /* QFLOAT_H */
diff --git a/qemu/include/qapi/qmp/qint.h b/qemu/include/qapi/qmp/qint.h
index 48a41b0f2..3aaff768d 100644
--- a/qemu/include/qapi/qmp/qint.h
+++ b/qemu/include/qapi/qmp/qint.h
@@ -13,16 +13,16 @@
#ifndef QINT_H
#define QINT_H
-#include <stdint.h>
#include "qapi/qmp/qobject.h"
typedef struct QInt {
- QObject_HEAD;
+ QObject base;
int64_t value;
} QInt;
QInt *qint_from_int(int64_t value);
int64_t qint_get_int(const QInt *qi);
QInt *qobject_to_qint(const QObject *obj);
+void qint_destroy_obj(QObject *obj);
#endif /* QINT_H */
diff --git a/qemu/include/qapi/qmp/qjson.h b/qemu/include/qapi/qmp/qjson.h
index ee4d31a46..02b1f2ce3 100644
--- a/qemu/include/qapi/qmp/qjson.h
+++ b/qemu/include/qapi/qmp/qjson.h
@@ -14,8 +14,6 @@
#ifndef QJSON_H
#define QJSON_H
-#include <stdarg.h>
-#include "qemu/compiler.h"
#include "qapi/qmp/qobject.h"
#include "qapi/qmp/qstring.h"
diff --git a/qemu/include/qapi/qmp/qlist.h b/qemu/include/qapi/qmp/qlist.h
index 6cc4831df..a84117ecb 100644
--- a/qemu/include/qapi/qmp/qlist.h
+++ b/qemu/include/qapi/qmp/qlist.h
@@ -22,7 +22,7 @@ typedef struct QListEntry {
} QListEntry;
typedef struct QList {
- QObject_HEAD;
+ QObject base;
QTAILQ_HEAD(,QListEntry) head;
} QList;
@@ -49,6 +49,7 @@ QObject *qlist_peek(QList *qlist);
int qlist_empty(const QList *qlist);
size_t qlist_size(const QList *qlist);
QList *qobject_to_qlist(const QObject *obj);
+void qlist_destroy_obj(QObject *obj);
static inline const QListEntry *qlist_first(const QList *qlist)
{
diff --git a/qemu/include/qapi/qmp/qobject.h b/qemu/include/qapi/qmp/qobject.h
index 260d2ed3c..b8ddbca40 100644
--- a/qemu/include/qapi/qmp/qobject.h
+++ b/qemu/include/qapi/qmp/qobject.h
@@ -32,36 +32,12 @@
#ifndef QOBJECT_H
#define QOBJECT_H
-#include <stddef.h>
-#include <assert.h>
+#include "qapi-types.h"
-typedef enum {
- QTYPE_NONE, /* sentinel value, no QObject has this type code */
- QTYPE_QNULL,
- QTYPE_QINT,
- QTYPE_QSTRING,
- QTYPE_QDICT,
- QTYPE_QLIST,
- QTYPE_QFLOAT,
- QTYPE_QBOOL,
- QTYPE_MAX,
-} qtype_code;
-
-struct QObject;
-
-typedef struct QType {
- qtype_code code;
- void (*destroy)(struct QObject *);
-} QType;
-
-typedef struct QObject {
- const QType *type;
+struct QObject {
+ QType type;
size_t refcnt;
-} QObject;
-
-/* Objects definitions must include this */
-#define QObject_HEAD \
- QObject base
+};
/* Get the 'base' part of an object */
#define QOBJECT(obj) (&(obj)->base)
@@ -75,9 +51,12 @@ typedef struct QObject {
qobject_decref(obj ? QOBJECT(obj) : NULL)
/* Initialize an object to default values */
-#define QOBJECT_INIT(obj, qtype_type) \
- obj->base.refcnt = 1; \
- obj->base.type = qtype_type
+static inline void qobject_init(QObject *obj, QType type)
+{
+ assert(QTYPE_NONE < type && type < QTYPE__MAX);
+ obj->refcnt = 1;
+ obj->type = type;
+}
/**
* qobject_incref(): Increment QObject's reference count
@@ -89,25 +68,29 @@ static inline void qobject_incref(QObject *obj)
}
/**
+ * qobject_destroy(): Free resources used by the object
+ */
+void qobject_destroy(QObject *obj);
+
+/**
* qobject_decref(): Decrement QObject's reference count, deallocate
* when it reaches zero
*/
static inline void qobject_decref(QObject *obj)
{
+ assert(!obj || obj->refcnt);
if (obj && --obj->refcnt == 0) {
- assert(obj->type != NULL);
- assert(obj->type->destroy != NULL);
- obj->type->destroy(obj);
+ qobject_destroy(obj);
}
}
/**
* qobject_type(): Return the QObject's type
*/
-static inline qtype_code qobject_type(const QObject *obj)
+static inline QType qobject_type(const QObject *obj)
{
- assert(obj->type != NULL);
- return obj->type->code;
+ assert(QTYPE_NONE < obj->type && obj->type < QTYPE__MAX);
+ return obj->type;
}
extern QObject qnull_;
diff --git a/qemu/include/qapi/qmp/qstring.h b/qemu/include/qapi/qmp/qstring.h
index 1bc366610..10076b7c8 100644
--- a/qemu/include/qapi/qmp/qstring.h
+++ b/qemu/include/qapi/qmp/qstring.h
@@ -13,11 +13,10 @@
#ifndef QSTRING_H
#define QSTRING_H
-#include <stdint.h>
#include "qapi/qmp/qobject.h"
typedef struct QString {
- QObject_HEAD;
+ QObject base;
char *string;
size_t length;
size_t capacity;
@@ -32,5 +31,6 @@ void qstring_append_int(QString *qstring, int64_t value);
void qstring_append(QString *qstring, const char *str);
void qstring_append_chr(QString *qstring, int c);
QString *qobject_to_qstring(const QObject *obj);
+void qstring_destroy_obj(QObject *obj);
#endif /* QSTRING_H */
diff --git a/qemu/include/qapi/visitor-impl.h b/qemu/include/qapi/visitor-impl.h
index f4a2f746c..2bd8f292b 100644
--- a/qemu/include/qapi/visitor-impl.h
+++ b/qemu/include/qapi/visitor-impl.h
@@ -1,7 +1,7 @@
/*
* Core Definitions for QAPI Visitor implementations
*
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2012-2016 Red Hat, Inc.
*
* Author: Paolo Bonizni <pbonzini@redhat.com>
*
@@ -12,56 +12,57 @@
#ifndef QAPI_VISITOR_IMPL_H
#define QAPI_VISITOR_IMPL_H
-#include "qapi/error.h"
#include "qapi/visitor.h"
struct Visitor
{
/* Must be set */
- void (*start_struct)(Visitor *v, void **obj, const char *kind,
- const char *name, size_t size, Error **errp);
+ void (*start_struct)(Visitor *v, const char *name, void **obj,
+ size_t size, Error **errp);
void (*end_struct)(Visitor *v, Error **errp);
- void (*start_implicit_struct)(Visitor *v, void **obj, size_t size,
- Error **errp);
- void (*end_implicit_struct)(Visitor *v, Error **errp);
-
void (*start_list)(Visitor *v, const char *name, Error **errp);
- GenericList *(*next_list)(Visitor *v, GenericList **list, Error **errp);
- void (*end_list)(Visitor *v, Error **errp);
+ /* Must be set */
+ GenericList *(*next_list)(Visitor *v, GenericList **list, size_t size);
+ /* Must be set */
+ void (*end_list)(Visitor *v);
- void (*type_enum)(Visitor *v, int *obj, const char * const strings[],
- const char *kind, const char *name, Error **errp);
- void (*get_next_type)(Visitor *v, int *kind, const int *qobjects,
- const char *name, Error **errp);
+ /* Optional, needed for input and dealloc visitors. */
+ void (*start_alternate)(Visitor *v, const char *name,
+ GenericAlternate **obj, size_t size,
+ bool promote_int, Error **errp);
- void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp);
- void (*type_bool)(Visitor *v, bool *obj, const char *name, Error **errp);
- void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
- void (*type_number)(Visitor *v, double *obj, const char *name,
- Error **errp);
+ /* Optional, needed for dealloc visitor. */
+ void (*end_alternate)(Visitor *v);
- /* May be NULL */
- void (*optional)(Visitor *v, bool *present, const char *name,
+ /* Must be set. */
+ void (*type_enum)(Visitor *v, const char *name, int *obj,
+ const char *const strings[], Error **errp);
+
+ /* Must be set. */
+ void (*type_int64)(Visitor *v, const char *name, int64_t *obj,
+ Error **errp);
+ /* Must be set. */
+ void (*type_uint64)(Visitor *v, const char *name, uint64_t *obj,
+ Error **errp);
+ /* Optional; fallback is type_uint64(). */
+ void (*type_size)(Visitor *v, const char *name, uint64_t *obj,
+ Error **errp);
+ /* Must be set. */
+ void (*type_bool)(Visitor *v, const char *name, bool *obj, Error **errp);
+ void (*type_str)(Visitor *v, const char *name, char **obj, Error **errp);
+ void (*type_number)(Visitor *v, const char *name, double *obj,
+ Error **errp);
+ void (*type_any)(Visitor *v, const char *name, QObject **obj,
Error **errp);
- void (*type_uint8)(Visitor *v, uint8_t *obj, const char *name, Error **errp);
- void (*type_uint16)(Visitor *v, uint16_t *obj, const char *name, Error **errp);
- void (*type_uint32)(Visitor *v, uint32_t *obj, const char *name, Error **errp);
- void (*type_uint64)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
- void (*type_int8)(Visitor *v, int8_t *obj, const char *name, Error **errp);
- void (*type_int16)(Visitor *v, int16_t *obj, const char *name, Error **errp);
- void (*type_int32)(Visitor *v, int32_t *obj, const char *name, Error **errp);
- void (*type_int64)(Visitor *v, int64_t *obj, const char *name, Error **errp);
- /* visit_type_size() falls back to (*type_uint64)() if type_size is unset */
- void (*type_size)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
- bool (*start_union)(Visitor *v, bool data_present, Error **errp);
- void (*end_union)(Visitor *v, bool data_present, Error **errp);
+ /* May be NULL; most useful for input visitors. */
+ void (*optional)(Visitor *v, const char *name, bool *present);
};
-void input_type_enum(Visitor *v, int *obj, const char * const strings[],
- const char *kind, const char *name, Error **errp);
-void output_type_enum(Visitor *v, int *obj, const char * const strings[],
- const char *kind, const char *name, Error **errp);
+void input_type_enum(Visitor *v, const char *name, int *obj,
+ const char *const strings[], Error **errp);
+void output_type_enum(Visitor *v, const char *name, int *obj,
+ const char *const strings[], Error **errp);
#endif
diff --git a/qemu/include/qapi/visitor.h b/qemu/include/qapi/visitor.h
index 00ba104cd..9a8d0105f 100644
--- a/qemu/include/qapi/visitor.h
+++ b/qemu/include/qapi/visitor.h
@@ -1,6 +1,7 @@
/*
* Core Definitions for QAPI Visitor Classes
*
+ * Copyright (C) 2012-2016 Red Hat, Inc.
* Copyright IBM, Corp. 2011
*
* Authors:
@@ -13,52 +14,94 @@
#ifndef QAPI_VISITOR_CORE_H
#define QAPI_VISITOR_CORE_H
-#include "qemu/typedefs.h"
#include "qapi/qmp/qobject.h"
-#include "qapi/error.h"
-#include <stdlib.h>
-typedef struct GenericList
-{
- union {
- void *value;
- uint64_t padding;
- };
+/* This struct is layout-compatible with all other *List structs
+ * created by the qapi generator. It is used as a typical
+ * singly-linked list. */
+typedef struct GenericList {
struct GenericList *next;
+ char padding[];
} GenericList;
-void visit_start_handle(Visitor *v, void **obj, const char *kind,
- const char *name, Error **errp);
-void visit_end_handle(Visitor *v, Error **errp);
-void visit_start_struct(Visitor *v, void **obj, const char *kind,
- const char *name, size_t size, Error **errp);
+/* This struct is layout-compatible with all Alternate types
+ * created by the qapi generator. */
+typedef struct GenericAlternate {
+ QType type;
+ char padding[];
+} GenericAlternate;
+
+void visit_start_struct(Visitor *v, const char *name, void **obj,
+ size_t size, Error **errp);
void visit_end_struct(Visitor *v, Error **errp);
-void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
- Error **errp);
-void visit_end_implicit_struct(Visitor *v, Error **errp);
+
void visit_start_list(Visitor *v, const char *name, Error **errp);
-GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp);
-void visit_end_list(Visitor *v, Error **errp);
-void visit_optional(Visitor *v, bool *present, const char *name,
- Error **errp);
-void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
- const char *name, Error **errp);
-void visit_type_enum(Visitor *v, int *obj, const char * const strings[],
- const char *kind, const char *name, Error **errp);
-void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp);
-void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp);
-void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp);
-void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp);
-void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp);
-void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp);
-void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp);
-void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp);
-void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp);
-void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp);
-void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp);
-void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp);
-void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp);
-bool visit_start_union(Visitor *v, bool data_present, Error **errp);
-void visit_end_union(Visitor *v, bool data_present, Error **errp);
+GenericList *visit_next_list(Visitor *v, GenericList **list, size_t size);
+void visit_end_list(Visitor *v);
+
+/*
+ * Start the visit of an alternate @obj with the given @size.
+ *
+ * @name specifies the relationship to the containing struct (ignored
+ * for a top level visit, the name of the key if this alternate is
+ * part of an object, or NULL if this alternate is part of a list).
+ *
+ * @obj must not be NULL. Input visitors will allocate @obj and
+ * determine the qtype of the next thing to be visited, stored in
+ * (*@obj)->type. Other visitors will leave @obj unchanged.
+ *
+ * If @promote_int, treat integers as QTYPE_FLOAT.
+ *
+ * If successful, this must be paired with visit_end_alternate(), even
+ * if visiting the contents of the alternate fails.
+ */
+void visit_start_alternate(Visitor *v, const char *name,
+ GenericAlternate **obj, size_t size,
+ bool promote_int, Error **errp);
+
+/*
+ * Finish visiting an alternate type.
+ *
+ * Must be called after a successful visit_start_alternate(), even if
+ * an error occurred in the meantime.
+ *
+ * TODO: Should all the visit_end_* interfaces take obj parameter, so
+ * that dealloc visitor need not track what was passed in visit_start?
+ */
+void visit_end_alternate(Visitor *v);
+
+/**
+ * Check if an optional member @name of an object needs visiting.
+ * For input visitors, set *@present according to whether the
+ * corresponding visit_type_*() needs calling; for other visitors,
+ * leave *@present unchanged. Return *@present for convenience.
+ */
+bool visit_optional(Visitor *v, const char *name, bool *present);
+
+void visit_type_enum(Visitor *v, const char *name, int *obj,
+ const char *const strings[], Error **errp);
+void visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp);
+void visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
+ Error **errp);
+void visit_type_uint16(Visitor *v, const char *name, uint16_t *obj,
+ Error **errp);
+void visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
+ Error **errp);
+void visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
+ Error **errp);
+void visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp);
+void visit_type_int16(Visitor *v, const char *name, int16_t *obj,
+ Error **errp);
+void visit_type_int32(Visitor *v, const char *name, int32_t *obj,
+ Error **errp);
+void visit_type_int64(Visitor *v, const char *name, int64_t *obj,
+ Error **errp);
+void visit_type_size(Visitor *v, const char *name, uint64_t *obj,
+ Error **errp);
+void visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp);
+void visit_type_str(Visitor *v, const char *name, char **obj, Error **errp);
+void visit_type_number(Visitor *v, const char *name, double *obj,
+ Error **errp);
+void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp);
#endif