aboutsummaryrefslogtreecommitdiff
path: root/softmmu
diff options
context:
space:
mode:
authorMarkus Armbruster <armbru@redhat.com>2023-01-24 13:19:39 +0100
committerMarkus Armbruster <armbru@redhat.com>2023-02-04 07:56:54 +0100
commit9c9c5ce7f7d63e654d21a61c58366a7306bcab9f (patch)
tree909951e3309a96cbc03308413656896b135a92f4 /softmmu
parent5bd26d78d9629a9d3f4780a162f09272978eae3d (diff)
downloadqemu-9c9c5ce7f7d63e654d21a61c58366a7306bcab9f.zip
qemu-9c9c5ce7f7d63e654d21a61c58366a7306bcab9f.tar.gz
qemu-9c9c5ce7f7d63e654d21a61c58366a7306bcab9f.tar.bz2
qdev: Move HMP command completion from monitor to softmmu/
This moves the completion code from MAINTAINERS sections "Human Monitor (HMP)" and "QMP" to section "QOM". Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20230124121946.1139465-26-armbru@redhat.com>
Diffstat (limited to 'softmmu')
-rw-r--r--softmmu/qdev-monitor.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index 4b0ef65..b8d2c4d 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -973,6 +973,88 @@ void hmp_device_del(Monitor *mon, const QDict *qdict)
hmp_handle_error(mon, err);
}
+void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+ GSList *list, *elt;
+ size_t len;
+
+ if (nb_args != 2) {
+ return;
+ }
+
+ len = strlen(str);
+ readline_set_completion_index(rs, len);
+ list = elt = object_class_get_list(TYPE_DEVICE, false);
+ while (elt) {
+ DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data,
+ TYPE_DEVICE);
+
+ if (dc->user_creatable) {
+ readline_add_completion_of(rs, str,
+ object_class_get_name(OBJECT_CLASS(dc)));
+ }
+ elt = elt->next;
+ }
+ g_slist_free(list);
+}
+
+static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
+{
+ GSList **list = opaque;
+ DeviceState *dev = (DeviceState *)object_dynamic_cast(obj, TYPE_DEVICE);
+
+ if (dev == NULL) {
+ return 0;
+ }
+
+ if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) {
+ *list = g_slist_append(*list, dev);
+ }
+
+ return 0;
+}
+
+static GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
+{
+ GSList *list = NULL;
+
+ object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);
+
+ return list;
+}
+
+static void peripheral_device_del_completion(ReadLineState *rs,
+ const char *str)
+{
+ Object *peripheral = container_get(qdev_get_machine(), "/peripheral");
+ GSList *list, *item;
+
+ list = qdev_build_hotpluggable_device_list(peripheral);
+ if (!list) {
+ return;
+ }
+
+ for (item = list; item; item = g_slist_next(item)) {
+ DeviceState *dev = item->data;
+
+ if (dev->id) {
+ readline_add_completion_of(rs, str, dev->id);
+ }
+ }
+
+ g_slist_free(list);
+}
+
+void device_del_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+ if (nb_args != 2) {
+ return;
+ }
+
+ readline_set_completion_index(rs, strlen(str));
+ peripheral_device_del_completion(rs, str);
+}
+
BlockBackend *blk_by_qdev_id(const char *id, Error **errp)
{
DeviceState *dev;