aboutsummaryrefslogtreecommitdiff
path: root/qom/object_interfaces.c
diff options
context:
space:
mode:
Diffstat (limited to 'qom/object_interfaces.c')
-rw-r--r--qom/object_interfaces.c172
1 files changed, 88 insertions, 84 deletions
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 7661270b98..b17aa57de1 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -2,15 +2,19 @@
#include "qemu/cutils.h"
#include "qapi/error.h"
+#include "qapi/qapi-commands-qom.h"
+#include "qapi/qapi-visit-qom.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qobject-input-visitor.h"
+#include "qapi/qobject-output-visitor.h"
#include "qom/object_interfaces.h"
#include "qemu/help_option.h"
#include "qemu/id.h"
#include "qemu/module.h"
#include "qemu/option.h"
+#include "qemu/qemu-print.h"
#include "qapi/opts-visitor.h"
#include "qemu/config-file.h"
@@ -113,90 +117,28 @@ out:
return obj;
}
-bool user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp)
+void user_creatable_add_qapi(ObjectOptions *options, Error **errp)
{
Visitor *v;
+ QObject *qobj;
+ QDict *props;
Object *obj;
- g_autofree char *type = NULL;
- g_autofree char *id = NULL;
- type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
- if (!type) {
- error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
- return false;
- }
- qdict_del(qdict, "qom-type");
-
- id = g_strdup(qdict_get_try_str(qdict, "id"));
- if (!id) {
- error_setg(errp, QERR_MISSING_PARAMETER, "id");
- return false;
- }
- qdict_del(qdict, "id");
-
- if (keyval) {
- v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
- } else {
- v = qobject_input_visitor_new(QOBJECT(qdict));
- }
- obj = user_creatable_add_type(type, id, qdict, v, errp);
- visit_free(v);
- object_unref(obj);
- return !!obj;
-}
-
-Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
-{
- Visitor *v;
- QDict *pdict;
- Object *obj;
- const char *id = qemu_opts_id(opts);
- char *type = qemu_opt_get_del(opts, "qom-type");
-
- if (!type) {
- error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
- return NULL;
- }
- if (!id) {
- error_setg(errp, QERR_MISSING_PARAMETER, "id");
- qemu_opt_set(opts, "qom-type", type, &error_abort);
- g_free(type);
- return NULL;
- }
-
- qemu_opts_set_id(opts, NULL);
- pdict = qemu_opts_to_qdict(opts, NULL);
-
- v = opts_visitor_new(opts);
- obj = user_creatable_add_type(type, id, pdict, v, errp);
+ v = qobject_output_visitor_new(&qobj);
+ visit_type_ObjectOptions(v, NULL, &options, &error_abort);
+ visit_complete(v, &qobj);
visit_free(v);
- qemu_opts_set_id(opts, (char *) id);
- qemu_opt_set(opts, "qom-type", type, &error_abort);
- g_free(type);
- qobject_unref(pdict);
- return obj;
-}
-
+ props = qobject_to(QDict, qobj);
+ qdict_del(props, "qom-type");
+ qdict_del(props, "id");
-int user_creatable_add_opts_foreach(void *opaque, QemuOpts *opts, Error **errp)
-{
- bool (*type_opt_predicate)(const char *, QemuOpts *) = opaque;
- Object *obj = NULL;
- const char *type;
-
- type = qemu_opt_get(opts, "qom-type");
- if (type && type_opt_predicate &&
- !type_opt_predicate(type, opts)) {
- return 0;
- }
-
- obj = user_creatable_add_opts(opts, errp);
- if (!obj) {
- return -1;
- }
+ v = qobject_input_visitor_new(QOBJECT(props));
+ obj = user_creatable_add_type(ObjectType_str(options->qom_type),
+ options->id, props, v, errp);
object_unref(obj);
- return 0;
+ qobject_unref(qobj);
+ visit_free(v);
}
char *object_property_help(const char *name, const char *type,
@@ -227,11 +169,11 @@ static void user_creatable_print_types(void)
{
GSList *l, *list;
- printf("List of user creatable objects:\n");
+ qemu_printf("List of user creatable objects:\n");
list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
for (l = list; l != NULL; l = l->next) {
ObjectClass *oc = OBJECT_CLASS(l->data);
- printf(" %s\n", object_class_get_name(oc));
+ qemu_printf(" %s\n", object_class_get_name(oc));
}
g_slist_free(list);
}
@@ -262,12 +204,12 @@ static bool user_creatable_print_type_properites(const char *type)
}
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
if (array->len > 0) {
- printf("%s options:\n", type);
+ qemu_printf("%s options:\n", type);
} else {
- printf("There are no options for %s.\n", type);
+ qemu_printf("There are no options for %s.\n", type);
}
for (i = 0; i < array->len; i++) {
- printf("%s\n", (char *)array->pdata[i]);
+ qemu_printf("%s\n", (char *)array->pdata[i]);
}
g_ptr_array_set_free_func(array, g_free);
g_ptr_array_free(array, true);
@@ -288,7 +230,7 @@ bool user_creatable_print_help(const char *type, QemuOpts *opts)
return false;
}
-void user_creatable_print_help_from_qdict(QDict *args)
+static void user_creatable_print_help_from_qdict(QDict *args)
{
const char *type = qdict_get_try_str(args, "qom-type");
@@ -297,8 +239,68 @@ void user_creatable_print_help_from_qdict(QDict *args)
}
}
+ObjectOptions *user_creatable_parse_str(const char *optarg, Error **errp)
+{
+ ERRP_GUARD();
+ QObject *obj;
+ bool help;
+ Visitor *v;
+ ObjectOptions *options;
+
+ if (optarg[0] == '{') {
+ obj = qobject_from_json(optarg, errp);
+ if (!obj) {
+ return NULL;
+ }
+ v = qobject_input_visitor_new(obj);
+ } else {
+ QDict *args = keyval_parse(optarg, "qom-type", &help, errp);
+ if (*errp) {
+ return NULL;
+ }
+ if (help) {
+ user_creatable_print_help_from_qdict(args);
+ qobject_unref(args);
+ return NULL;
+ }
+
+ obj = QOBJECT(args);
+ v = qobject_input_visitor_new_keyval(obj);
+ }
+
+ visit_type_ObjectOptions(v, NULL, &options, errp);
+ visit_free(v);
+ qobject_unref(obj);
+
+ return options;
+}
+
+bool user_creatable_add_from_str(const char *optarg, Error **errp)
+{
+ ERRP_GUARD();
+ ObjectOptions *options;
+
+ options = user_creatable_parse_str(optarg, errp);
+ if (!options) {
+ return false;
+ }
+
+ user_creatable_add_qapi(options, errp);
+ qapi_free_ObjectOptions(options);
+ return !*errp;
+}
+
+void user_creatable_process_cmdline(const char *optarg)
+{
+ if (!user_creatable_add_from_str(optarg, &error_fatal)) {
+ /* Help was printed */
+ exit(EXIT_SUCCESS);
+ }
+}
+
bool user_creatable_del(const char *id, Error **errp)
{
+ QemuOptsList *opts_list;
Object *container;
Object *obj;
@@ -318,8 +320,10 @@ bool user_creatable_del(const char *id, Error **errp)
* if object was defined on the command-line, remove its corresponding
* option group entry
*/
- qemu_opts_del(qemu_opts_find(qemu_find_opts_err("object", &error_abort),
- id));
+ opts_list = qemu_find_opts_err("object", NULL);
+ if (opts_list) {
+ qemu_opts_del(qemu_opts_find(opts_list, id));
+ }
object_unparent(obj);
return true;