diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 61aba9fc548d..f70ff28c05db 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1516,6 +1516,7 @@ static void pc_generic_machine_class_init(ObjectClass *oc, void *data) MachineClass *mc = MACHINE_CLASS(oc); QEMUMachine *qm = data; + mc->family = qm->family; mc->name = qm->name; mc->alias = qm->alias; mc->desc = qm->desc; diff --git a/include/hw/boards.h b/include/hw/boards.h index e07c03f8466e..4429a1e3a222 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -19,6 +19,7 @@ typedef void QEMUMachineHotAddCPUFunc(const int64_t id, Error **errp); typedef int QEMUMachineGetKvmtypeFunc(const char *arg); struct QEMUMachine { + const char *family; /* NULL iff @name identifies a standalone machtype */ const char *name; const char *alias; const char *desc; @@ -76,6 +77,7 @@ struct MachineClass { ObjectClass parent_class; /*< public >*/ + const char *family; /* NULL iff @name identifies a standalone machtype */ const char *name; const char *alias; const char *desc; diff --git a/vl.c b/vl.c index f6b35469428f..d32efa0df062 100644 --- a/vl.c +++ b/vl.c @@ -1416,6 +1416,7 @@ static void machine_class_init(ObjectClass *oc, void *data) MachineClass *mc = MACHINE_CLASS(oc); QEMUMachine *qm = data; + mc->family = qm->family; mc->name = qm->name; mc->alias = qm->alias; mc->desc = qm->desc; @@ -2488,7 +2489,41 @@ static int debugcon_parse(const char *devname) return 0; } -static MachineClass *machine_parse(const char *name) +static gint machine_class_cmp(gconstpointer a, gconstpointer b) +{ + const MachineClass *mc1 = a, *mc2 = b; + int res; + + if (mc1->family == NULL) { + if (mc2->family == NULL) { + /* Compare standalone machine types against each other; they sort + * in increasing order. + */ + return strcmp(object_class_get_name(OBJECT_CLASS(mc1)), + object_class_get_name(OBJECT_CLASS(mc2))); + } + + /* Standalone machine types sort after families. */ + return 1; + } + + if (mc2->family == NULL) { + /* Families sort before standalone machine types. */ + return -1; + } + + /* Families sort between each other alphabetically increasingly. */ + res = strcmp(mc1->family, mc2->family); + if (res != 0) { + return res; + } + + /* Within the same family, machine types sort in decreasing order. */ + return strcmp(object_class_get_name(OBJECT_CLASS(mc2)), + object_class_get_name(OBJECT_CLASS(mc1))); +} + + static MachineClass *machine_parse(const char *name) { MachineClass *mc = NULL; GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false); @@ -2504,6 +2539,7 @@ static MachineClass *machine_parse(const char *name) error_printf("Use -machine help to list supported machines!\n"); } else { printf("Supported machines are:\n"); + machines = g_slist_sort(machines, machine_class_cmp); for (el = machines; el; el = el->next) { MachineClass *mc = el->data; if (mc->alias) {