[5/7] cpu: Let architectures set CPU class name format
diff mbox series

Message ID 20190419061429.17695-6-ehabkost@redhat.com
State New
Headers show
Series
  • Delete 16 *_cpu_class_by_name() functions
Related show

Commit Message

Eduardo Habkost April 19, 2019, 6:14 a.m. UTC
Instead of requiring every architecture to implement a
class_by_name function, let them set a format string at
CPUClass::class_name_format.

This will let us get rid of at least 16 class_by_name functions
in the next commits.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qom/cpu.h | 12 ++++++++++++
 qom/cpu.c         | 18 ++++++++++++++++--
 2 files changed, 28 insertions(+), 2 deletions(-)

Comments

Markus Armbruster May 6, 2019, 11:42 a.m. UTC | #1
Eduardo Habkost <ehabkost@redhat.com> writes:

> Instead of requiring every architecture to implement a
> class_by_name function, let them set a format string at
> CPUClass::class_name_format.
>
> This will let us get rid of at least 16 class_by_name functions
> in the next commits.
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  include/qom/cpu.h | 12 ++++++++++++
>  qom/cpu.c         | 18 ++++++++++++++++--
>  2 files changed, 28 insertions(+), 2 deletions(-)
>
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index fefd5c26b0..eda6a46b82 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -163,7 +163,19 @@ typedef struct CPUClass {
>      DeviceClass parent_class;
>      /*< public >*/
>  
> +    /* The following fields configure CPU model name -> QOM type translation: */
> +
> +    /*
> +     * arch-specific CPU model -> QOM type translation function.
> +     * Optional if @class_name_format is set.
> +     */
>      ObjectClass *(*class_by_name)(const char *cpu_model);
> +    /*
> +     * Format string for g_strdup_printf(), used to generate the CPU
> +     * class name.

Please document acceptable conversion specifiers.

> +     */
> +    const char *class_name_format;
> +
>      void (*parse_features)(const char *typename, char *str, Error **errp);
>  
>      void (*reset)(CPUState *cpu);
> diff --git a/qom/cpu.c b/qom/cpu.c
> index b971a56242..1fa64941b6 100644
> --- a/qom/cpu.c
> +++ b/qom/cpu.c
> @@ -286,9 +286,23 @@ static bool cpu_common_has_work(CPUState *cs)
>  CPUClass *cpu_class_by_name(const char *typename, const char *cpu_model)
>  {
>      CPUClass *cc = CPU_CLASS(object_class_by_name(typename));
> +    ObjectClass *oc;
> +    char *class_name;
>  
> -    assert(cpu_model && cc->class_by_name);
> -    return CPU_CLASS(cc->class_by_name(cpu_model));
> +    assert(cpu_model);
> +    if (cc->class_by_name) {
> +        return CPU_CLASS(cc->class_by_name(cpu_model));
> +    }
> +
> +    assert(cc->class_name_format);
> +    class_name = g_strdup_printf(cc->class_name_format, cpu_model);

Defeats -Wformat.  Triggers -Wformat-nonliteral, which we don't use, I
presume.  Observation, not objection.

cc->class_name_format must contain exactly one conversion specifier,
which must take a char *.

> +    oc = object_class_by_name(class_name);
> +    g_free(class_name);
> +    if (!oc || !object_class_dynamic_cast(oc, typename) ||
> +        object_class_is_abstract(oc)) {
> +        return NULL;
> +    }
> +    return CPU_CLASS(oc);
>  }
>  
>  static void cpu_common_parse_features(const char *typename, char *features,
Markus Armbruster May 8, 2019, 5:52 a.m. UTC | #2
Markus Armbruster <armbru@redhat.com> writes:

> Eduardo Habkost <ehabkost@redhat.com> writes:
>
>> Instead of requiring every architecture to implement a
>> class_by_name function, let them set a format string at
>> CPUClass::class_name_format.
>>
>> This will let us get rid of at least 16 class_by_name functions
>> in the next commits.
>>
>> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
>> ---
>>  include/qom/cpu.h | 12 ++++++++++++
>>  qom/cpu.c         | 18 ++++++++++++++++--
>>  2 files changed, 28 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
>> index fefd5c26b0..eda6a46b82 100644
>> --- a/include/qom/cpu.h
>> +++ b/include/qom/cpu.h
>> @@ -163,7 +163,19 @@ typedef struct CPUClass {
>>      DeviceClass parent_class;
>>      /*< public >*/
>>  
>> +    /* The following fields configure CPU model name -> QOM type translation: */
>> +
>> +    /*
>> +     * arch-specific CPU model -> QOM type translation function.
>> +     * Optional if @class_name_format is set.
>> +     */
>>      ObjectClass *(*class_by_name)(const char *cpu_model);
>> +    /*
>> +     * Format string for g_strdup_printf(), used to generate the CPU
>> +     * class name.
>
> Please document acceptable conversion specifiers.
>
>> +     */
>> +    const char *class_name_format;
>> +
>>      void (*parse_features)(const char *typename, char *str, Error **errp);
>>  
>>      void (*reset)(CPUState *cpu);
>> diff --git a/qom/cpu.c b/qom/cpu.c
>> index b971a56242..1fa64941b6 100644
>> --- a/qom/cpu.c
>> +++ b/qom/cpu.c
>> @@ -286,9 +286,23 @@ static bool cpu_common_has_work(CPUState *cs)
>>  CPUClass *cpu_class_by_name(const char *typename, const char *cpu_model)
>>  {
>>      CPUClass *cc = CPU_CLASS(object_class_by_name(typename));
>> +    ObjectClass *oc;
>> +    char *class_name;
>>  
>> -    assert(cpu_model && cc->class_by_name);
>> -    return CPU_CLASS(cc->class_by_name(cpu_model));
>> +    assert(cpu_model);
>> +    if (cc->class_by_name) {
>> +        return CPU_CLASS(cc->class_by_name(cpu_model));
>> +    }
>> +
>> +    assert(cc->class_name_format);
>> +    class_name = g_strdup_printf(cc->class_name_format, cpu_model);
>
> Defeats -Wformat.  Triggers -Wformat-nonliteral, which we don't use, I
> presume.  Observation, not objection.
>
> cc->class_name_format must contain exactly one conversion specifier,
> which must take a char *.

s/exactly one/at most one/

PATCH 7 defines formats without a conversion specifier.

>> +    oc = object_class_by_name(class_name);
>> +    g_free(class_name);
>> +    if (!oc || !object_class_dynamic_cast(oc, typename) ||
>> +        object_class_is_abstract(oc)) {
>> +        return NULL;
>> +    }
>> +    return CPU_CLASS(oc);
>>  }
>>  
>>  static void cpu_common_parse_features(const char *typename, char *features,

Patch
diff mbox series

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index fefd5c26b0..eda6a46b82 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -163,7 +163,19 @@  typedef struct CPUClass {
     DeviceClass parent_class;
     /*< public >*/
 
+    /* The following fields configure CPU model name -> QOM type translation: */
+
+    /*
+     * arch-specific CPU model -> QOM type translation function.
+     * Optional if @class_name_format is set.
+     */
     ObjectClass *(*class_by_name)(const char *cpu_model);
+    /*
+     * Format string for g_strdup_printf(), used to generate the CPU
+     * class name.
+     */
+    const char *class_name_format;
+
     void (*parse_features)(const char *typename, char *str, Error **errp);
 
     void (*reset)(CPUState *cpu);
diff --git a/qom/cpu.c b/qom/cpu.c
index b971a56242..1fa64941b6 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -286,9 +286,23 @@  static bool cpu_common_has_work(CPUState *cs)
 CPUClass *cpu_class_by_name(const char *typename, const char *cpu_model)
 {
     CPUClass *cc = CPU_CLASS(object_class_by_name(typename));
+    ObjectClass *oc;
+    char *class_name;
 
-    assert(cpu_model && cc->class_by_name);
-    return CPU_CLASS(cc->class_by_name(cpu_model));
+    assert(cpu_model);
+    if (cc->class_by_name) {
+        return CPU_CLASS(cc->class_by_name(cpu_model));
+    }
+
+    assert(cc->class_name_format);
+    class_name = g_strdup_printf(cc->class_name_format, cpu_model);
+    oc = object_class_by_name(class_name);
+    g_free(class_name);
+    if (!oc || !object_class_dynamic_cast(oc, typename) ||
+        object_class_is_abstract(oc)) {
+        return NULL;
+    }
+    return CPU_CLASS(oc);
 }
 
 static void cpu_common_parse_features(const char *typename, char *features,