All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] qom: Use qlit to represent property defaults
@ 2020-11-09 21:25 Eduardo Habkost
  2020-11-09 21:25 ` [PATCH 1/8] qobject: Include API docs in docs/devel/qobject.html Eduardo Habkost
                   ` (9 more replies)
  0 siblings, 10 replies; 12+ messages in thread
From: Eduardo Habkost @ 2020-11-09 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Daniel P. Berrangé,
	Markus Armbruster, Eduardo Habkost

Based-on: 20201104160021.2342108-1-ehabkost@redhat.com
Git branch: https://gitlab.com/ehabkost/qemu/-/commits/work/qdev-qlit-defaults

This extend qlit.h to support all QNum types (signed int,
unsigned int, and double), and use QLitObject to represent field
property defaults.

It allows us to get rid of most type-specific .set_default_value
functions for QOM property types.

Eduardo Habkost (8):
  qobject: Include API docs in docs/devel/qobject.html
  qnum: Make qnum_get_double() get const pointer
  qnum: QNumValue type for QNum value literals
  qnum: qnum_value_is_equal() function
  qlit: Support all types of QNums
  qlit: qlit_type() function
  qom: Make object_property_set_default() public
  qom: Use qlit to represent property defaults

 docs/devel/index.rst                  |   1 +
 docs/devel/qobject.rst                |  11 +++
 include/hw/qdev-properties-system.h   |   2 +-
 include/qapi/qmp/qlit.h               |  16 +++-
 include/qapi/qmp/qnum.h               |  47 ++++++++++-
 include/qapi/qmp/qobject.h            |  48 +++++++----
 include/qom/field-property-internal.h |   4 -
 include/qom/field-property.h          |  26 +++---
 include/qom/object.h                  |  11 +++
 include/qom/property-types.h          |  21 ++---
 hw/core/qdev-properties-system.c      |   8 --
 qobject/qlit.c                        |   4 +-
 qobject/qnum.c                        | 116 +++++++++++++++-----------
 qom/field-property.c                  |  27 ++++--
 qom/object.c                          |   2 +-
 qom/property-types.c                  |  36 ++------
 tests/check-qjson.c                   |  72 ++++++++++++++--
 17 files changed, 295 insertions(+), 157 deletions(-)
 create mode 100644 docs/devel/qobject.rst

-- 
2.28.0




^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/8] qobject: Include API docs in docs/devel/qobject.html
  2020-11-09 21:25 [PATCH 0/8] qom: Use qlit to represent property defaults Eduardo Habkost
@ 2020-11-09 21:25 ` Eduardo Habkost
  2020-11-09 21:25 ` [PATCH 2/8] qnum: Make qnum_get_double() get const pointer Eduardo Habkost
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eduardo Habkost @ 2020-11-09 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Daniel P. Berrangé,
	Markus Armbruster, Eduardo Habkost

Render existing doc comments at docs/devel/qobject.html.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 docs/devel/index.rst       |  1 +
 docs/devel/qobject.rst     | 11 +++++++++
 include/qapi/qmp/qnum.h    |  4 +++-
 include/qapi/qmp/qobject.h | 48 +++++++++++++++++++++++++-------------
 qobject/qnum.c             | 19 ++++++++++++---
 5 files changed, 63 insertions(+), 20 deletions(-)
 create mode 100644 docs/devel/qobject.rst

diff --git a/docs/devel/index.rst b/docs/devel/index.rst
index 77baae5c77..7f8e5e3071 100644
--- a/docs/devel/index.rst
+++ b/docs/devel/index.rst
@@ -34,3 +34,4 @@ Contents:
    clocks
    qom
    block-coroutine-wrapper
+   qobject
diff --git a/docs/devel/qobject.rst b/docs/devel/qobject.rst
new file mode 100644
index 0000000000..4f192ced7c
--- /dev/null
+++ b/docs/devel/qobject.rst
@@ -0,0 +1,11 @@
+QObject API
+===========
+
+.. kernel-doc:: include/qapi/qmp/qobject.h
+
+QNum module
+-----------
+
+.. kernel-doc:: include/qapi/qmp/qnum.h
+
+.. kernel-doc:: qobject/qnum.c
diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index bbae0a5ec8..25f4733efc 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -23,7 +23,9 @@ typedef enum {
     QNUM_DOUBLE
 } QNumKind;
 
-/*
+/**
+ * DOC:
+ *
  * QNum encapsulates how our dialect of JSON fills in the blanks left
  * by the JSON specification (RFC 8259) regarding numbers.
  *
diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
index fcfd549220..bdc33bdb65 100644
--- a/include/qapi/qmp/qobject.h
+++ b/include/qapi/qmp/qobject.h
@@ -1,5 +1,5 @@
 /*
- * QEMU Object Model.
+ * QObject API
  *
  * Based on ideas by Avi Kivity <avi@redhat.com>
  *
@@ -10,24 +10,31 @@
  *
  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
  * See the COPYING.LIB file in the top-level directory.
+ */
+
+/**
+ * DOC: QObject Reference Counts Terminology
  *
- * QObject Reference Counts Terminology
- * ------------------------------------
+ * Returning references
+ * --------------------
  *
- *  - Returning references: A function that returns an object may
- *  return it as either a weak or a strong reference.  If the
- *  reference is strong, you are responsible for calling
- *  qobject_unref() on the reference when you are done.
+ * A function that returns an object may return it as either a
+ * weak or a strong reference.  If the reference is strong, you
+ * are responsible for calling qobject_unref() on the reference
+ * when you are done.
  *
- *  If the reference is weak, the owner of the reference may free it at
- *  any time in the future.  Before storing the reference anywhere, you
- *  should call qobject_ref() to make the reference strong.
+ * If the reference is weak, the owner of the reference may free it at
+ * any time in the future.  Before storing the reference anywhere, you
+ * should call qobject_ref() to make the reference strong.
  *
- *  - Transferring ownership: when you transfer ownership of a reference
- *  by calling a function, you are no longer responsible for calling
- *  qobject_unref() when the reference is no longer needed.  In other words,
- *  when the function returns you must behave as if the reference to the
- *  passed object was weak.
+ * Transferring ownership
+ * ----------------------
+ *
+ * When you transfer ownership of a reference by calling a
+ * function, you are no longer responsible for calling
+ * qobject_unref() when the reference is no longer needed.  In
+ * other words, when the function returns you must behave as if
+ * the reference to the passed object was weak.
  */
 #ifndef QOBJECT_H
 #define QOBJECT_H
@@ -81,6 +88,8 @@ static inline void qobject_ref_impl(QObject *obj)
 
 /**
  * qobject_is_equal(): Return whether the two objects are equal.
+ * @x: QObject pointer
+ * @y: QObject pointer
  *
  * Any of the pointers may be NULL; return true if both are.  Always
  * return false if only one is (therefore a QNull object is not
@@ -90,6 +99,7 @@ bool qobject_is_equal(const QObject *x, const QObject *y);
 
 /**
  * qobject_destroy(): Free resources used by the object
+ * @obj: QObject pointer
  */
 void qobject_destroy(QObject *obj);
 
@@ -103,6 +113,7 @@ static inline void qobject_unref_impl(QObject *obj)
 
 /**
  * qobject_ref(): Increment QObject's reference count
+ * @obj: QObject pointer
  *
  * Returns: the same @obj. The type of @obj will be propagated to the
  * return type.
@@ -115,12 +126,14 @@ static inline void qobject_unref_impl(QObject *obj)
 
 /**
  * qobject_unref(): Decrement QObject's reference count, deallocate
- * when it reaches zero
+ *                  when it reaches zero
+ * @obj: QObject pointer
  */
 #define qobject_unref(obj) qobject_unref_impl(QOBJECT(obj))
 
 /**
  * qobject_type(): Return the QObject's type
+ * @obj: QObject pointer
  */
 static inline QType qobject_type(const QObject *obj)
 {
@@ -130,6 +143,9 @@ static inline QType qobject_type(const QObject *obj)
 
 /**
  * qobject_check_type(): Helper function for the qobject_to() macro.
+ * @obj: QObject pointer
+ * @type: Expected type of QObject
+ *
  * Return @obj, but only if @obj is not NULL and @type is equal to
  * @obj's type.  Return NULL otherwise.
  */
diff --git a/qobject/qnum.c b/qobject/qnum.c
index 7012fc57f2..017c8aa739 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -17,6 +17,7 @@
 
 /**
  * qnum_from_int(): Create a new QNum from an int64_t
+ * @value: int64_t value
  *
  * Return strong reference.
  */
@@ -33,6 +34,7 @@ QNum *qnum_from_int(int64_t value)
 
 /**
  * qnum_from_uint(): Create a new QNum from an uint64_t
+ * @value: uint64_t value
  *
  * Return strong reference.
  */
@@ -49,6 +51,7 @@ QNum *qnum_from_uint(uint64_t value)
 
 /**
  * qnum_from_double(): Create a new QNum from a double
+ * @value: double value
  *
  * Return strong reference.
  */
@@ -65,6 +68,8 @@ QNum *qnum_from_double(double value)
 
 /**
  * qnum_get_try_int(): Get an integer representation of the number
+ * @qn: QNum object
+ * @val: pointer to value
  *
  * Return true on success.
  */
@@ -90,6 +95,7 @@ bool qnum_get_try_int(const QNum *qn, int64_t *val)
 
 /**
  * qnum_get_int(): Get an integer representation of the number
+ * @qn: QNum object
  *
  * assert() on failure.
  */
@@ -102,7 +108,9 @@ int64_t qnum_get_int(const QNum *qn)
 }
 
 /**
- * qnum_get_uint(): Get an unsigned integer from the number
+ * qnum_value_get_try_uint(): Get an unsigned integer from the number
+ * @qn: QNum object
+ * @val: pointer to value
  *
  * Return true on success.
  */
@@ -128,6 +136,7 @@ bool qnum_get_try_uint(const QNum *qn, uint64_t *val)
 
 /**
  * qnum_get_uint(): Get an unsigned integer from the number
+ * @qn: QNum object
  *
  * assert() on failure.
  */
@@ -141,6 +150,7 @@ uint64_t qnum_get_uint(const QNum *qn)
 
 /**
  * qnum_get_double(): Get a float representation of the number
+ * @qn: QNum object
  *
  * qnum_get_double() loses precision for integers beyond 53 bits.
  */
@@ -200,6 +210,8 @@ char *qnum_to_string(QNum *qn)
 
 /**
  * qnum_is_equal(): Test whether the two QNums are equal
+ * @x: QNum object
+ * @y: QNum object
  *
  * Negative integers are never considered equal to unsigned integers,
  * but positive integers in the range [0, INT64_MAX] are considered
@@ -253,8 +265,9 @@ bool qnum_is_equal(const QObject *x, const QObject *y)
 }
 
 /**
- * qnum_destroy_obj(): Free all memory allocated by a
- * QNum object
+ * qnum_destroy_obj(): Free all memory allocated by a QNum object
+ *
+ * @obj: QNum object to be destroyed
  */
 void qnum_destroy_obj(QObject *obj)
 {
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/8] qnum: Make qnum_get_double() get const pointer
  2020-11-09 21:25 [PATCH 0/8] qom: Use qlit to represent property defaults Eduardo Habkost
  2020-11-09 21:25 ` [PATCH 1/8] qobject: Include API docs in docs/devel/qobject.html Eduardo Habkost
@ 2020-11-09 21:25 ` Eduardo Habkost
  2020-11-09 21:25 ` [PATCH 3/8] qnum: QNumValue type for QNum value literals Eduardo Habkost
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eduardo Habkost @ 2020-11-09 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Daniel P. Berrangé,
	Markus Armbruster, Eduardo Habkost

qnum_get_double() won't change the object, the argument can be
const.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qapi/qmp/qnum.h | 2 +-
 qobject/qnum.c          | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index 25f4733efc..55c27b1c24 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -66,7 +66,7 @@ int64_t qnum_get_int(const QNum *qn);
 bool qnum_get_try_uint(const QNum *qn, uint64_t *val);
 uint64_t qnum_get_uint(const QNum *qn);
 
-double qnum_get_double(QNum *qn);
+double qnum_get_double(const QNum *qn);
 
 char *qnum_to_string(QNum *qn);
 
diff --git a/qobject/qnum.c b/qobject/qnum.c
index 017c8aa739..69fd9a82d9 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -154,7 +154,7 @@ uint64_t qnum_get_uint(const QNum *qn)
  *
  * qnum_get_double() loses precision for integers beyond 53 bits.
  */
-double qnum_get_double(QNum *qn)
+double qnum_get_double(const QNum *qn)
 {
     switch (qn->kind) {
     case QNUM_I64:
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/8] qnum: QNumValue type for QNum value literals
  2020-11-09 21:25 [PATCH 0/8] qom: Use qlit to represent property defaults Eduardo Habkost
  2020-11-09 21:25 ` [PATCH 1/8] qobject: Include API docs in docs/devel/qobject.html Eduardo Habkost
  2020-11-09 21:25 ` [PATCH 2/8] qnum: Make qnum_get_double() get const pointer Eduardo Habkost
@ 2020-11-09 21:25 ` Eduardo Habkost
  2020-11-09 21:25 ` [PATCH 4/8] qnum: qnum_value_is_equal() function Eduardo Habkost
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eduardo Habkost @ 2020-11-09 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Daniel P. Berrangé,
	Markus Armbruster, Eduardo Habkost

Provide a separate QNumValue type that can be used for QNum value
literals without the referencing counting and memory allocation
features provided by QObject.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qapi/qmp/qnum.h | 40 +++++++++++++++++++--
 qobject/qnum.c          | 78 ++++++++++++++++++++---------------------
 2 files changed, 77 insertions(+), 41 deletions(-)

diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index 55c27b1c24..62fbdfda68 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -46,20 +46,56 @@ typedef enum {
  * in range: qnum_get_try_int() / qnum_get_try_uint() check range and
  * convert under the hood.
  */
-struct QNum {
-    struct QObjectBase_ base;
+
+/**
+ * struct QNumValue: the value of a QNum
+ *
+ * QNumValue literals can be constructed using the `QNUM_VAL_INT`,
+ * `QNUM_VAL_UINT`, and `QNUM_VAL_DOUBLE` macros.
+ */
+typedef struct QNumValue {
+    /* private: */
     QNumKind kind;
     union {
         int64_t i64;
         uint64_t u64;
         double dbl;
     } u;
+} QNumValue;
+
+#define QNUM_VAL_INT(value) \
+    { .kind = QNUM_I64, .u.i64 = value }
+#define QNUM_VAL_UINT(value) \
+    { .kind = QNUM_U64, .u.u64 = value }
+#define QNUM_VAL_DOUBLE(value) \
+    { .kind = QNUM_DOUBLE, .u.dbl = value }
+
+struct QNum {
+    struct QObjectBase_ base;
+    QNumValue value;
 };
 
+/**
+ * qnum_from_int(): Create a new QNum from a QNumValue
+ * @value: QNumValue
+ *
+ * Return strong reference.
+ */
+QNum *qnum_from_value(QNumValue value);
+
 QNum *qnum_from_int(int64_t value);
 QNum *qnum_from_uint(uint64_t value);
 QNum *qnum_from_double(double value);
 
+/**
+ * qnum_get_value(): Get QNumValue from QNum
+ * @qn: QNum object
+ */
+static inline const QNumValue *qnum_get_value(const QNum *qn)
+{
+    return &qn->value;
+}
+
 bool qnum_get_try_int(const QNum *qn, int64_t *val);
 int64_t qnum_get_int(const QNum *qn);
 
diff --git a/qobject/qnum.c b/qobject/qnum.c
index 69fd9a82d9..f80d4efd76 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -15,6 +15,15 @@
 #include "qemu/osdep.h"
 #include "qapi/qmp/qnum.h"
 
+QNum *qnum_from_value(QNumValue value)
+{
+    QNum *qn = g_new(QNum, 1);
+
+    qobject_init(QOBJECT(qn), QTYPE_QNUM);
+    qn->value = value;
+    return qn;
+}
+
 /**
  * qnum_from_int(): Create a new QNum from an int64_t
  * @value: int64_t value
@@ -23,13 +32,7 @@
  */
 QNum *qnum_from_int(int64_t value)
 {
-    QNum *qn = g_new(QNum, 1);
-
-    qobject_init(QOBJECT(qn), QTYPE_QNUM);
-    qn->kind = QNUM_I64;
-    qn->u.i64 = value;
-
-    return qn;
+    return qnum_from_value((QNumValue) QNUM_VAL_INT(value));
 }
 
 /**
@@ -40,13 +43,7 @@ QNum *qnum_from_int(int64_t value)
  */
 QNum *qnum_from_uint(uint64_t value)
 {
-    QNum *qn = g_new(QNum, 1);
-
-    qobject_init(QOBJECT(qn), QTYPE_QNUM);
-    qn->kind = QNUM_U64;
-    qn->u.u64 = value;
-
-    return qn;
+    return qnum_from_value((QNumValue) QNUM_VAL_UINT(value));
 }
 
 /**
@@ -57,13 +54,7 @@ QNum *qnum_from_uint(uint64_t value)
  */
 QNum *qnum_from_double(double value)
 {
-    QNum *qn = g_new(QNum, 1);
-
-    qobject_init(QOBJECT(qn), QTYPE_QNUM);
-    qn->kind = QNUM_DOUBLE;
-    qn->u.dbl = value;
-
-    return qn;
+    return qnum_from_value((QNumValue) QNUM_VAL_DOUBLE(value));
 }
 
 /**
@@ -75,15 +66,17 @@ QNum *qnum_from_double(double value)
  */
 bool qnum_get_try_int(const QNum *qn, int64_t *val)
 {
-    switch (qn->kind) {
+    const QNumValue *qv = &qn->value;
+
+    switch (qv->kind) {
     case QNUM_I64:
-        *val = qn->u.i64;
+        *val = qv->u.i64;
         return true;
     case QNUM_U64:
-        if (qn->u.u64 > INT64_MAX) {
+        if (qv->u.u64 > INT64_MAX) {
             return false;
         }
-        *val = qn->u.u64;
+        *val = qv->u.u64;
         return true;
     case QNUM_DOUBLE:
         return false;
@@ -116,15 +109,17 @@ int64_t qnum_get_int(const QNum *qn)
  */
 bool qnum_get_try_uint(const QNum *qn, uint64_t *val)
 {
-    switch (qn->kind) {
+    const QNumValue *qv = &qn->value;
+
+    switch (qv->kind) {
     case QNUM_I64:
-        if (qn->u.i64 < 0) {
+        if (qv->u.i64 < 0) {
             return false;
         }
-        *val = qn->u.i64;
+        *val = qv->u.i64;
         return true;
     case QNUM_U64:
-        *val = qn->u.u64;
+        *val = qv->u.u64;
         return true;
     case QNUM_DOUBLE:
         return false;
@@ -156,13 +151,15 @@ uint64_t qnum_get_uint(const QNum *qn)
  */
 double qnum_get_double(const QNum *qn)
 {
-    switch (qn->kind) {
+    const QNumValue *qv = &qn->value;
+
+    switch (qv->kind) {
     case QNUM_I64:
-        return qn->u.i64;
+        return qv->u.i64;
     case QNUM_U64:
-        return qn->u.u64;
+        return qv->u.u64;
     case QNUM_DOUBLE:
-        return qn->u.dbl;
+        return qv->u.dbl;
     }
 
     assert(0);
@@ -171,14 +168,15 @@ double qnum_get_double(const QNum *qn)
 
 char *qnum_to_string(QNum *qn)
 {
+    const QNumValue *qv = &qn->value;
     char *buffer;
     int len;
 
-    switch (qn->kind) {
+    switch (qv->kind) {
     case QNUM_I64:
-        return g_strdup_printf("%" PRId64, qn->u.i64);
+        return g_strdup_printf("%" PRId64, qv->u.i64);
     case QNUM_U64:
-        return g_strdup_printf("%" PRIu64, qn->u.u64);
+        return g_strdup_printf("%" PRIu64, qv->u.u64);
     case QNUM_DOUBLE:
         /* FIXME: snprintf() is locale dependent; but JSON requires
          * numbers to be formatted as if in the C locale. Dependence
@@ -189,7 +187,7 @@ char *qnum_to_string(QNum *qn)
          * rounding errors; we should be using DBL_DECIMAL_DIG (17),
          * and only rounding to a shorter number if the result would
          * still produce the same floating point value.  */
-        buffer = g_strdup_printf("%f" , qn->u.dbl);
+        buffer = g_strdup_printf("%f" , qv->u.dbl);
         len = strlen(buffer);
         while (len > 0 && buffer[len - 1] == '0') {
             len--;
@@ -221,8 +219,10 @@ char *qnum_to_string(QNum *qn)
  */
 bool qnum_is_equal(const QObject *x, const QObject *y)
 {
-    QNum *num_x = qobject_to(QNum, x);
-    QNum *num_y = qobject_to(QNum, y);
+    const QNum *qnum_x = qobject_to(QNum, x);
+    const QNum *qnum_y = qobject_to(QNum, y);
+    const QNumValue *num_x = &qnum_x->value;
+    const QNumValue *num_y = &qnum_y->value;
 
     switch (num_x->kind) {
     case QNUM_I64:
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/8] qnum: qnum_value_is_equal() function
  2020-11-09 21:25 [PATCH 0/8] qom: Use qlit to represent property defaults Eduardo Habkost
                   ` (2 preceding siblings ...)
  2020-11-09 21:25 ` [PATCH 3/8] qnum: QNumValue type for QNum value literals Eduardo Habkost
@ 2020-11-09 21:25 ` Eduardo Habkost
  2020-11-09 21:25 ` [PATCH 5/8] qlit: Support all types of QNums Eduardo Habkost
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eduardo Habkost @ 2020-11-09 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Daniel P. Berrangé,
	Markus Armbruster, Eduardo Habkost

Extract the QNum value comparison logic to a function that takes
QNumValue* as argument.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qapi/qmp/qnum.h |  1 +
 qobject/qnum.c          | 29 +++++++++++++++++++----------
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index 62fbdfda68..0327ecd0f0 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -106,6 +106,7 @@ double qnum_get_double(const QNum *qn);
 
 char *qnum_to_string(QNum *qn);
 
+bool qnum_value_is_equal(const QNumValue *num_x, const QNumValue *num_y);
 bool qnum_is_equal(const QObject *x, const QObject *y);
 void qnum_destroy_obj(QObject *obj);
 
diff --git a/qobject/qnum.c b/qobject/qnum.c
index f80d4efd76..6a0f948b16 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -207,9 +207,9 @@ char *qnum_to_string(QNum *qn)
 }
 
 /**
- * qnum_is_equal(): Test whether the two QNums are equal
- * @x: QNum object
- * @y: QNum object
+ * qnum_value_is_equal(): Test whether two QNumValues are equal
+ * @num_x: QNum value
+ * @num_y: QNum value
  *
  * Negative integers are never considered equal to unsigned integers,
  * but positive integers in the range [0, INT64_MAX] are considered
@@ -217,13 +217,8 @@ char *qnum_to_string(QNum *qn)
  *
  * Doubles are never considered equal to integers.
  */
-bool qnum_is_equal(const QObject *x, const QObject *y)
+bool qnum_value_is_equal(const QNumValue *num_x, const QNumValue *num_y)
 {
-    const QNum *qnum_x = qobject_to(QNum, x);
-    const QNum *qnum_y = qobject_to(QNum, y);
-    const QNumValue *num_x = &qnum_x->value;
-    const QNumValue *num_y = &qnum_y->value;
-
     switch (num_x->kind) {
     case QNUM_I64:
         switch (num_y->kind) {
@@ -241,7 +236,7 @@ bool qnum_is_equal(const QObject *x, const QObject *y)
     case QNUM_U64:
         switch (num_y->kind) {
         case QNUM_I64:
-            return qnum_is_equal(y, x);
+            return qnum_value_is_equal(num_y, num_x);
         case QNUM_U64:
             /* Comparison in native uint64_t type */
             return num_x->u.u64 == num_y->u.u64;
@@ -264,6 +259,20 @@ bool qnum_is_equal(const QObject *x, const QObject *y)
     abort();
 }
 
+/**
+ * qnum_is_equal(): Test whether the two QNums are equal
+ * @x: QNum object
+ * @y: QNum object
+ *
+ * See qnum_value_is_equal() for details on the comparison rules.
+ */
+bool qnum_is_equal(const QObject *x, const QObject *y)
+{
+    const QNum *qnum_x = qobject_to(QNum, x);
+    const QNum *qnum_y = qobject_to(QNum, y);
+    return qnum_value_is_equal(&qnum_x->value, &qnum_y->value);
+}
+
 /**
  * qnum_destroy_obj(): Free all memory allocated by a QNum object
  *
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/8] qlit: Support all types of QNums
  2020-11-09 21:25 [PATCH 0/8] qom: Use qlit to represent property defaults Eduardo Habkost
                   ` (3 preceding siblings ...)
  2020-11-09 21:25 ` [PATCH 4/8] qnum: qnum_value_is_equal() function Eduardo Habkost
@ 2020-11-09 21:25 ` Eduardo Habkost
  2020-11-09 21:25 ` [PATCH 6/8] qlit: qlit_type() function Eduardo Habkost
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eduardo Habkost @ 2020-11-09 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Daniel P. Berrangé,
	Markus Armbruster, Eduardo Habkost

Use QNumValue to represent QNums, so we can also support uint64_t
and double QNum values.  Add new QLIT_QNUM_(INT|UINT|DOUBLE)
macros for each case.

The QLIT_QNUM() macro is being kept for compatibility with
existing code, but becomes just a wrapper for QLIT_QNUM_INT().

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qapi/qmp/qlit.h | 11 +++++--
 qobject/qlit.c          |  4 +--
 tests/check-qjson.c     | 72 ++++++++++++++++++++++++++++++++++++++---
 3 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index c0676d5daf..f9e356d31e 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -15,6 +15,7 @@
 #define QLIT_H
 
 #include "qobject.h"
+#include "qnum.h"
 
 typedef struct QLitDictEntry QLitDictEntry;
 typedef struct QLitObject QLitObject;
@@ -23,7 +24,7 @@ struct QLitObject {
     QType type;
     union {
         bool qbool;
-        int64_t qnum;
+        QNumValue qnum;
         const char *qstr;
         QLitDictEntry *qdict;
         QLitObject *qlist;
@@ -39,8 +40,14 @@ struct QLitDictEntry {
     { .type = QTYPE_QNULL }
 #define QLIT_QBOOL(val) \
     { .type = QTYPE_QBOOL, .value.qbool = (val) }
+#define QLIT_QNUM_INT(val) \
+    { .type = QTYPE_QNUM, .value.qnum = QNUM_VAL_INT(val) }
+#define QLIT_QNUM_UINT(val) \
+    { .type = QTYPE_QNUM, .value.qnum = QNUM_VAL_UINT(val) }
+#define QLIT_QNUM_DOUBLE(val) \
+    { .type = QTYPE_QNUM, .value.qnum = QNUM_VAL_DOUBLE(val) }
 #define QLIT_QNUM(val) \
-    { .type = QTYPE_QNUM, .value.qnum = (val) }
+    QLIT_QNUM_INT(val)
 #define QLIT_QSTR(val) \
     { .type = QTYPE_QSTRING, .value.qstr = (val) }
 #define QLIT_QDICT(val) \
diff --git a/qobject/qlit.c b/qobject/qlit.c
index be8332136c..ec11a39518 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -71,7 +71,7 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
     case QTYPE_QBOOL:
         return lhs->value.qbool == qbool_get_bool(qobject_to(QBool, rhs));
     case QTYPE_QNUM:
-        return lhs->value.qnum ==  qnum_get_int(qobject_to(QNum, rhs));
+        return qnum_value_is_equal(&lhs->value.qnum, qnum_get_value(qobject_to(QNum, rhs)));
     case QTYPE_QSTRING:
         return (strcmp(lhs->value.qstr,
                        qstring_get_str(qobject_to(QString, rhs))) == 0);
@@ -94,7 +94,7 @@ QObject *qobject_from_qlit(const QLitObject *qlit)
     case QTYPE_QNULL:
         return QOBJECT(qnull());
     case QTYPE_QNUM:
-        return QOBJECT(qnum_from_int(qlit->value.qnum));
+        return QOBJECT(qnum_from_value(qlit->value.qnum));
     case QTYPE_QSTRING:
         return QOBJECT(qstring_from_str(qlit->value.qstr));
     case QTYPE_QDICT: {
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 07a773e653..711030cffd 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -796,20 +796,23 @@ static void simple_number(void)
     int i;
     struct {
         const char *encoded;
+        QLitObject qlit;
         int64_t decoded;
         int skip;
     } test_cases[] = {
-        { "0", 0 },
-        { "1234", 1234 },
-        { "1", 1 },
-        { "-32", -32 },
-        { "-0", 0, .skip = 1 },
+        { "0",    QLIT_QNUM(0),    0, },
+        { "1234", QLIT_QNUM(1234), 1234, },
+        { "1",    QLIT_QNUM(1),    1, },
+        { "-32",  QLIT_QNUM(-32),  -32, },
+        { "-0",   QLIT_QNUM(0),    0, .skip = 1 },
         { },
     };
 
     for (i = 0; test_cases[i].encoded; i++) {
         QNum *qnum;
         int64_t val;
+        QNum *qlit_num;
+        int64_t qlit_val;
 
         qnum = qobject_to(QNum,
                           qobject_from_json(test_cases[i].encoded,
@@ -817,6 +820,7 @@ static void simple_number(void)
         g_assert(qnum);
         g_assert(qnum_get_try_int(qnum, &val));
         g_assert_cmpint(val, ==, test_cases[i].decoded);
+
         if (test_cases[i].skip == 0) {
             QString *str;
 
@@ -826,9 +830,66 @@ static void simple_number(void)
         }
 
         qobject_unref(qnum);
+
+        qlit_num = qobject_to(QNum,
+                              qobject_from_qlit(&test_cases[i].qlit));
+        g_assert(qlit_num);
+        g_assert(qnum_get_try_int(qlit_num, &qlit_val));
+        g_assert_cmpint(qlit_val, ==, test_cases[i].decoded);
+
+        qobject_unref(qlit_num);
     }
 }
 
+static void qlit_large_number(void)
+{
+    QLitObject maxu64 = QLIT_QNUM_UINT(UINT64_MAX);
+    QLitObject maxi64 = QLIT_QNUM(INT64_MAX);
+    QLitObject mini64 = QLIT_QNUM(INT64_MIN);
+    QLitObject gtu64  = QLIT_QNUM_DOUBLE(18446744073709552e3);
+    QLitObject lti64  = QLIT_QNUM_DOUBLE(-92233720368547758e2);
+    QNum *qnum;
+    uint64_t val;
+    int64_t ival;
+
+    qnum = qobject_to(QNum, qobject_from_qlit(&maxu64));
+    g_assert(qnum);
+    g_assert_cmpuint(qnum_get_uint(qnum), ==, UINT64_MAX);
+    g_assert(!qnum_get_try_int(qnum, &ival));
+
+    qobject_unref(qnum);
+
+    qnum = qobject_to(QNum, qobject_from_qlit(&maxi64));
+    g_assert(qnum);
+    g_assert_cmpuint(qnum_get_uint(qnum), ==, INT64_MAX);
+    g_assert_cmpint(qnum_get_int(qnum), ==, INT64_MAX);
+
+    qobject_unref(qnum);
+
+    qnum = qobject_to(QNum, qobject_from_qlit(&mini64));
+    g_assert(qnum);
+    g_assert(!qnum_get_try_uint(qnum, &val));
+    g_assert_cmpuint(qnum_get_int(qnum), ==, INT64_MIN);
+
+    qobject_unref(qnum);
+
+    qnum = qobject_to(QNum, qobject_from_qlit(&gtu64));
+    g_assert(qnum);
+    g_assert_cmpfloat(qnum_get_double(qnum), ==, 18446744073709552e3);
+    g_assert(!qnum_get_try_uint(qnum, &val));
+    g_assert(!qnum_get_try_int(qnum, &ival));
+
+    qobject_unref(qnum);
+
+    qnum = qobject_to(QNum, qobject_from_qlit(&lti64));
+    g_assert(qnum);
+    g_assert_cmpfloat(qnum_get_double(qnum), ==, -92233720368547758e2);
+    g_assert(!qnum_get_try_uint(qnum, &val));
+    g_assert(!qnum_get_try_int(qnum, &ival));
+
+    qobject_unref(qnum);
+}
+
 static void large_number(void)
 {
     const char *maxu64 = "18446744073709551615"; /* 2^64-1 */
@@ -1472,6 +1533,7 @@ int main(int argc, char **argv)
     g_test_add_func("/literals/string/utf8", utf8_string);
 
     g_test_add_func("/literals/number/simple", simple_number);
+    g_test_add_func("/literals/number/qlit_large", qlit_large_number);
     g_test_add_func("/literals/number/large", large_number);
     g_test_add_func("/literals/number/float", float_number);
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/8] qlit: qlit_type() function
  2020-11-09 21:25 [PATCH 0/8] qom: Use qlit to represent property defaults Eduardo Habkost
                   ` (4 preceding siblings ...)
  2020-11-09 21:25 ` [PATCH 5/8] qlit: Support all types of QNums Eduardo Habkost
@ 2020-11-09 21:25 ` Eduardo Habkost
  2020-11-09 21:25 ` [PATCH 7/8] qom: Make object_property_set_default() public Eduardo Habkost
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eduardo Habkost @ 2020-11-09 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Daniel P. Berrangé,
	Markus Armbruster, Eduardo Habkost

Useful function where we need to check for the qlit type before
converting it to an actual QObject.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qapi/qmp/qlit.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index f9e356d31e..acddb80831 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -59,4 +59,9 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs);
 
 QObject *qobject_from_qlit(const QLitObject *qlit);
 
+static inline QType qlit_type(const QLitObject *qlit)
+{
+    return qlit->type;
+}
+
 #endif /* QLIT_H */
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 7/8] qom: Make object_property_set_default() public
  2020-11-09 21:25 [PATCH 0/8] qom: Use qlit to represent property defaults Eduardo Habkost
                   ` (5 preceding siblings ...)
  2020-11-09 21:25 ` [PATCH 6/8] qlit: qlit_type() function Eduardo Habkost
@ 2020-11-09 21:25 ` Eduardo Habkost
  2020-11-09 21:25 ` [PATCH 8/8] qom: Use qlit to represent property defaults Eduardo Habkost
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eduardo Habkost @ 2020-11-09 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Daniel P. Berrangé,
	Markus Armbruster, Eduardo Habkost

The function will be used outside qom/object.c, to simplify the
field property code that sets the property default value.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qom/object.h | 11 +++++++++++
 qom/object.c         |  2 +-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 2ab124b8f0..4234cc9b66 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1090,6 +1090,17 @@ ObjectProperty *object_class_property_add(ObjectClass *klass, const char *name,
                                           ObjectPropertyRelease *release,
                                           void *opaque);
 
+/**
+ * object_property_set_default:
+ * @prop: the property to set
+ * @value: the value to be written to the property
+ *
+ * Set the property default value.
+ *
+ * Ownership of @value is transferred to the property.
+ */
+void object_property_set_default(ObjectProperty *prop, QObject *value);
+
 /**
  * object_property_set_default_bool:
  * @prop: the property to set
diff --git a/qom/object.c b/qom/object.c
index 7c11bcd3b1..6b0d9d8c79 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1547,7 +1547,7 @@ static void object_property_init_defval(Object *obj, ObjectProperty *prop)
     visit_free(v);
 }
 
-static void object_property_set_default(ObjectProperty *prop, QObject *defval)
+void object_property_set_default(ObjectProperty *prop, QObject *defval)
 {
     assert(!prop->defval);
     assert(!prop->init);
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 8/8] qom: Use qlit to represent property defaults
  2020-11-09 21:25 [PATCH 0/8] qom: Use qlit to represent property defaults Eduardo Habkost
                   ` (6 preceding siblings ...)
  2020-11-09 21:25 ` [PATCH 7/8] qom: Make object_property_set_default() public Eduardo Habkost
@ 2020-11-09 21:25 ` Eduardo Habkost
  2020-11-09 21:39 ` [PATCH 0/8] " no-reply
  2020-11-10 16:39 ` Paolo Bonzini
  9 siblings, 0 replies; 12+ messages in thread
From: Eduardo Habkost @ 2020-11-09 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Daniel P. Berrangé,
	Markus Armbruster, Eduardo Habkost

Using QLitObject lets us get rid of most of the
.set_default_value functions, and just use
object_property_set_default() directly.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/hw/qdev-properties-system.h   |  2 +-
 include/qom/field-property-internal.h |  4 ---
 include/qom/field-property.h          | 26 ++++++++-----------
 include/qom/property-types.h          | 21 +++++++---------
 hw/core/qdev-properties-system.c      |  8 ------
 qom/field-property.c                  | 27 ++++++++++++++------
 qom/property-types.c                  | 36 ++++-----------------------
 7 files changed, 44 insertions(+), 80 deletions(-)

diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
index 0ac327ae60..a586424a33 100644
--- a/include/hw/qdev-properties-system.h
+++ b/include/hw/qdev-properties-system.h
@@ -65,7 +65,7 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
 
 #define DEFINE_PROP_UUID(_name, _state, _field) \
     DEFINE_PROP(_name, _state, _field, qdev_prop_uuid, QemuUUID, \
-                .set_default = true)
+                .defval = QLIT_QSTR("auto"))
 
 #define DEFINE_PROP_AUDIODEV(_n, _s, _f) \
     DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard)
diff --git a/include/qom/field-property-internal.h b/include/qom/field-property-internal.h
index 7aa27ce836..09877d9d6f 100644
--- a/include/qom/field-property-internal.h
+++ b/include/qom/field-property-internal.h
@@ -15,10 +15,6 @@ void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
 
 void field_prop_set_default_value_enum(ObjectProperty *op,
                                        const Property *prop);
-void field_prop_set_default_value_int(ObjectProperty *op,
-                                      const Property *prop);
-void field_prop_set_default_value_uint(ObjectProperty *op,
-                                       const Property *prop);
 
 void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp);
diff --git a/include/qom/field-property.h b/include/qom/field-property.h
index bc866e1c93..b83b424a5e 100644
--- a/include/qom/field-property.h
+++ b/include/qom/field-property.h
@@ -6,6 +6,7 @@
 
 #include "qom/object.h"
 #include "qapi/util.h"
+#include "qapi/qmp/qlit.h"
 
 /**
  * struct Property: definition of a field property
@@ -29,21 +30,8 @@ struct Property {
     const PropertyInfo *info;
     ptrdiff_t    offset;
     uint8_t      bitnr;
-    /**
-     * @set_default: true if the default value should be set from @defval,
-     *    in which case @info->set_default_value must not be NULL
-     *    (if false then no default value is set by the property system
-     *     and the field retains whatever value it was given by instance_init).
-     */
-    bool         set_default;
-    /**
-     * @defval: default value for the property. This is used only if @set_default
-     *     is true.
-     */
-    union {
-        int64_t i;
-        uint64_t u;
-    } defval;
+    /** @defval: If not QNull, the default value for the property */
+    QLitObject defval;
     /* private: */
     int          arrayoffset;
     const PropertyInfo *arrayinfo;
@@ -63,7 +51,13 @@ struct PropertyInfo {
     const QEnumLookup *enum_table;
     /** @print: String formatting function, for the human monitor */
     int (*print)(Object *obj, Property *prop, char *dest, size_t len);
-    /** @set_default_value: Callback for initializing the default value */
+    /**
+     * @set_default_value: Optional callback for initializing the default value
+     *
+     * Most property types don't need to set this, as by default
+     * object_property_set_default() is called with the value at
+     * Property.defval.
+     */
     void (*set_default_value)(ObjectProperty *op, const Property *prop);
     /** @create: Optional callback for creation of property */
     ObjectProperty *(*create)(ObjectClass *oc, const char *name,
diff --git a/include/qom/property-types.h b/include/qom/property-types.h
index 3a36e1fec5..36ca6f9e55 100644
--- a/include/qom/property-types.h
+++ b/include/qom/property-types.h
@@ -5,6 +5,7 @@
 #define QOM_PROPERTY_TYPES_H
 
 #include "qom/field-property.h"
+#include "qapi/qmp/qlit.h"
 
 extern const PropertyInfo prop_info_bit;
 extern const PropertyInfo prop_info_bit64;
@@ -28,13 +29,14 @@ extern const PropertyInfo prop_info_link;
         .info      = &(_prop),                                   \
         .offset    = offsetof(_state, _field)                    \
             + type_check(_type, typeof_field(_state, _field)),   \
+        .defval = QLIT_QNULL,                                    \
+        /* Note that __VA_ARGS__ can still override .defval */   \
         __VA_ARGS__                                              \
         }
 
 #define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \
     DEFINE_PROP(_name, _state, _field, _prop, _type,                     \
-                .set_default = true,                                     \
-                .defval.i    = (_type)_defval)
+                .defval = QLIT_QNUM_INT(_defval))
 
 #define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
     DEFINE_PROP(_name, _state, _field, _prop, _type)
@@ -50,13 +52,11 @@ extern const PropertyInfo prop_info_link;
 #define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
     DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \
                 .bitnr       = (_bit),                          \
-                .set_default = true,                            \
-                .defval.u    = (bool)_defval)
+                .defval = QLIT_QBOOL(_defval))
 
 #define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) \
     DEFINE_PROP(_name, _state, _field, _prop, _type,                       \
-                .set_default = true,                                       \
-                .defval.u  = (_type)_defval)
+                .defval = QLIT_QNUM_UINT(_defval))
 
 #define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
     DEFINE_PROP(_name, _state, _field, _prop, _type)
@@ -72,8 +72,7 @@ extern const PropertyInfo prop_info_link;
 #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval)   \
     DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \
                 .bitnr    = (_bit),                               \
-                .set_default = true,                              \
-                .defval.u  = (bool)_defval)
+                .defval = QLIT_QBOOL(_defval))
 
 /**
  * DEFINE_PROP_BOOL:
@@ -84,8 +83,7 @@ extern const PropertyInfo prop_info_link;
  */
 #define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
     DEFINE_PROP(_name, _state, _field, prop_info_bool, bool, \
-                .set_default = true,                         \
-                .defval.u    = (bool)_defval)
+                .defval = QLIT_QBOOL(_defval))
 
 #define PROP_ARRAY_LEN_PREFIX "len-"
 
@@ -118,8 +116,7 @@ extern const PropertyInfo prop_info_link;
                           _arrayfield, _arrayprop, _arraytype) \
     DEFINE_PROP((PROP_ARRAY_LEN_PREFIX _name),                 \
                 _state, _field, prop_info_arraylen, uint32_t,  \
-                .set_default = true,                           \
-                .defval.u = 0,                                 \
+                .defval = QLIT_QNUM_UINT(0),                   \
                 .arrayinfo = &(_arrayprop),                    \
                 .arrayfieldsize = sizeof(_arraytype),          \
                 .arrayoffset = offsetof(_state, _arrayfield))
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 8da68f076c..d9be5372f6 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -570,7 +570,6 @@ const PropertyInfo qdev_prop_blocksize = {
                    " and " MAX_BLOCK_SIZE_STR,
     .get   = field_prop_get_size32,
     .set   = set_blocksize,
-    .set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- Block device error handling policy --- */
@@ -768,7 +767,6 @@ const PropertyInfo qdev_prop_pci_devfn = {
     .print = print_pci_devfn,
     .get   = field_prop_get_int32,
     .set   = set_pci_devfn,
-    .set_default_value = field_prop_set_default_value_int,
 };
 
 /* --- pci host address --- */
@@ -1080,16 +1078,10 @@ static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
     g_free(str);
 }
 
-static void set_default_uuid_auto(ObjectProperty *op, const Property *prop)
-{
-    object_property_set_default_str(op, UUID_VALUE_AUTO);
-}
-
 const PropertyInfo qdev_prop_uuid = {
     .name  = "str",
     .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
         "\" for random value (default)",
     .get   = get_uuid,
     .set   = set_uuid,
-    .set_default_value = set_default_uuid_auto,
 };
diff --git a/qom/field-property.c b/qom/field-property.c
index 25a818bb69..727d7199ae 100644
--- a/qom/field-property.c
+++ b/qom/field-property.c
@@ -47,6 +47,20 @@ static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
     return info->set ? field_prop_set : NULL;
 }
 
+static void field_prop_set_default_value(ObjectProperty *op,
+                                         Property *prop)
+{
+    if (qlit_type(&prop->defval) == QTYPE_QNULL) {
+        return;
+    }
+
+    if (prop->info->set_default_value) {
+        prop->info->set_default_value(op, prop);
+    } else {
+        object_property_set_default(op, qobject_from_qlit(&prop->defval));
+    }
+}
+
 ObjectProperty *
 object_property_add_field(Object *obj, const char *name, Property *prop,
                           ObjectPropertyAllowSet allow_set)
@@ -65,11 +79,9 @@ object_property_add_field(Object *obj, const char *name, Property *prop,
     object_property_set_description(obj, name,
                                     prop->info->description);
 
-    if (prop->set_default) {
-        prop->info->set_default_value(op, prop);
-        if (op->init) {
-            op->init(obj, op);
-        }
+    field_prop_set_default_value(op, prop);
+    if (op->init) {
+        op->init(obj, op);
     }
 
     op->allow_set = allow_set;
@@ -95,9 +107,8 @@ object_class_property_add_field(ObjectClass *oc, const char *name,
                                        prop->info->release,
                                        prop);
     }
-    if (prop->set_default) {
-        prop->info->set_default_value(op, prop);
-    }
+
+    field_prop_set_default_value(op, prop);
     if (prop->info->description) {
         object_class_property_set_description(oc, name,
                                               prop->info->description);
diff --git a/qom/property-types.c b/qom/property-types.c
index f566c05ec2..8bed83c712 100644
--- a/qom/property-types.c
+++ b/qom/property-types.c
@@ -28,8 +28,11 @@ void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
 void field_prop_set_default_value_enum(ObjectProperty *op,
                                        const Property *prop)
 {
-    object_property_set_default_str(op,
-        qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
+    QObject *defval = qobject_from_qlit(&prop->defval);
+    const char *str = qapi_enum_lookup(prop->info->enum_table,
+                                       qnum_get_int(qobject_to(QNum, defval)));
+    object_property_set_default_str(op, str);
+    qobject_unref(defval);
 }
 
 const PropertyInfo prop_info_enum = {
@@ -80,17 +83,11 @@ static void prop_set_bit(Object *obj, Visitor *v, const char *name,
     bit_prop_set(obj, prop, value);
 }
 
-static void set_default_value_bool(ObjectProperty *op, const Property *prop)
-{
-    object_property_set_default_bool(op, prop->defval.u);
-}
-
 const PropertyInfo prop_info_bit = {
     .name  = "bool",
     .description = "on/off",
     .get   = prop_get_bit,
     .set   = prop_set_bit,
-    .set_default_value = set_default_value_bool,
 };
 
 /* Bit64 */
@@ -139,7 +136,6 @@ const PropertyInfo prop_info_bit64 = {
     .description = "on/off",
     .get   = prop_get_bit64,
     .set   = prop_set_bit64,
-    .set_default_value = set_default_value_bool,
 };
 
 /* --- bool --- */
@@ -166,7 +162,6 @@ const PropertyInfo prop_info_bool = {
     .name  = "bool",
     .get   = get_bool,
     .set   = set_bool,
-    .set_default_value = set_default_value_bool,
 };
 
 /* --- 8bit integer --- */
@@ -189,23 +184,10 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
     visit_type_uint8(v, name, ptr, errp);
 }
 
-void field_prop_set_default_value_int(ObjectProperty *op,
-                                      const Property *prop)
-{
-    object_property_set_default_int(op, prop->defval.i);
-}
-
-void field_prop_set_default_value_uint(ObjectProperty *op,
-                                       const Property *prop)
-{
-    object_property_set_default_uint(op, prop->defval.u);
-}
-
 const PropertyInfo prop_info_uint8 = {
     .name  = "uint8",
     .get   = get_uint8,
     .set   = set_uint8,
-    .set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- 16bit integer --- */
@@ -232,7 +214,6 @@ const PropertyInfo prop_info_uint16 = {
     .name  = "uint16",
     .get   = get_uint16,
     .set   = set_uint16,
-    .set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- 32bit integer --- */
@@ -277,14 +258,12 @@ const PropertyInfo prop_info_uint32 = {
     .name  = "uint32",
     .get   = get_uint32,
     .set   = set_uint32,
-    .set_default_value = field_prop_set_default_value_uint,
 };
 
 const PropertyInfo prop_info_int32 = {
     .name  = "int32",
     .get   = field_prop_get_int32,
     .set   = set_int32,
-    .set_default_value = field_prop_set_default_value_int,
 };
 
 /* --- 64bit integer --- */
@@ -329,14 +308,12 @@ const PropertyInfo prop_info_uint64 = {
     .name  = "uint64",
     .get   = get_uint64,
     .set   = set_uint64,
-    .set_default_value = field_prop_set_default_value_uint,
 };
 
 const PropertyInfo prop_info_int64 = {
     .name  = "int64",
     .get   = get_int64,
     .set   = set_int64,
-    .set_default_value = field_prop_set_default_value_int,
 };
 
 /* --- string --- */
@@ -431,7 +408,6 @@ const PropertyInfo prop_info_size32 = {
     .name  = "size",
     .get = field_prop_get_size32,
     .set = set_size32,
-    .set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- support for array properties --- */
@@ -494,7 +470,6 @@ const PropertyInfo prop_info_arraylen = {
     .name = "uint32",
     .get = get_uint32,
     .set = set_prop_arraylen,
-    .set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- 64bit unsigned int 'size' type --- */
@@ -521,7 +496,6 @@ const PropertyInfo prop_info_size = {
     .name  = "size",
     .get = get_size,
     .set = set_size,
-    .set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- object link property --- */
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/8] qom: Use qlit to represent property defaults
  2020-11-09 21:25 [PATCH 0/8] qom: Use qlit to represent property defaults Eduardo Habkost
                   ` (7 preceding siblings ...)
  2020-11-09 21:25 ` [PATCH 8/8] qom: Use qlit to represent property defaults Eduardo Habkost
@ 2020-11-09 21:39 ` no-reply
  2020-11-10 16:39 ` Paolo Bonzini
  9 siblings, 0 replies; 12+ messages in thread
From: no-reply @ 2020-11-09 21:39 UTC (permalink / raw)
  To: ehabkost; +Cc: pbonzini, berrange, qemu-devel, ehabkost, armbru

Patchew URL: https://patchew.org/QEMU/20201109212556.3934583-1-ehabkost@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 20201109212556.3934583-1-ehabkost@redhat.com
Subject: [PATCH 0/8] qom: Use qlit to represent property defaults
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/20201109212556.3934583-1-ehabkost@redhat.com -> patchew/20201109212556.3934583-1-ehabkost@redhat.com
Switched to a new branch 'test'
514115e qom: Use qlit to represent property defaults
2ca3561 qom: Make object_property_set_default() public
4c261ae qlit: qlit_type() function
8b601c4 qlit: Support all types of QNums
2d5f1af qnum: qnum_value_is_equal() function
be74c49 qnum: QNumValue type for QNum value literals
87b0edc qnum: Make qnum_get_double() get const pointer
ab4b510 qobject: Include API docs in docs/devel/qobject.html

=== OUTPUT BEGIN ===
1/8 Checking commit ab4b510c0e22 (qobject: Include API docs in docs/devel/qobject.html)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#23: 
new file mode 100644

total: 0 errors, 1 warnings, 201 lines checked

Patch 1/8 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
2/8 Checking commit 87b0edcb50a7 (qnum: Make qnum_get_double() get const pointer)
3/8 Checking commit be74c4978f05 (qnum: QNumValue type for QNum value literals)
4/8 Checking commit 2d5f1af84646 (qnum: qnum_value_is_equal() function)
5/8 Checking commit 8b601c44266e (qlit: Support all types of QNums)
ERROR: line over 90 characters
#64: FILE: qobject/qlit.c:74:
+        return qnum_value_is_equal(&lhs->value.qnum, qnum_get_value(qobject_to(QNum, rhs)));

total: 1 errors, 0 warnings, 154 lines checked

Patch 5/8 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

6/8 Checking commit 4c261ae4c3f2 (qlit: qlit_type() function)
7/8 Checking commit 2ca3561ee690 (qom: Make object_property_set_default() public)
8/8 Checking commit 514115e597f1 (qom: Use qlit to represent property defaults)
WARNING: Block comments use a leading /* on a separate line
#148: FILE: include/qom/property-types.h:33:
+        /* Note that __VA_ARGS__ can still override .defval */   \

total: 0 errors, 1 warnings, 325 lines checked

Patch 8/8 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20201109212556.3934583-1-ehabkost@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/8] qom: Use qlit to represent property defaults
  2020-11-09 21:25 [PATCH 0/8] qom: Use qlit to represent property defaults Eduardo Habkost
                   ` (8 preceding siblings ...)
  2020-11-09 21:39 ` [PATCH 0/8] " no-reply
@ 2020-11-10 16:39 ` Paolo Bonzini
  2020-11-10 18:16   ` Eduardo Habkost
  9 siblings, 1 reply; 12+ messages in thread
From: Paolo Bonzini @ 2020-11-10 16:39 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel; +Cc: Daniel P. Berrangé, Markus Armbruster

On 09/11/20 22:25, Eduardo Habkost wrote:
> Based-on: 20201104160021.2342108-1-ehabkost@redhat.com
> Git branch: https://gitlab.com/ehabkost/qemu/-/commits/work/qdev-qlit-defaults
> 
> This extend qlit.h to support all QNum types (signed int,
> unsigned int, and double), and use QLitObject to represent field
> property defaults.
> 
> It allows us to get rid of most type-specific .set_default_value
> functions for QOM property types.
> 
> Eduardo Habkost (8):
>    qobject: Include API docs in docs/devel/qobject.html
>    qnum: Make qnum_get_double() get const pointer
>    qnum: QNumValue type for QNum value literals
>    qnum: qnum_value_is_equal() function
>    qlit: Support all types of QNums
>    qlit: qlit_type() function
>    qom: Make object_property_set_default() public
>    qom: Use qlit to represent property defaults
> 
>   docs/devel/index.rst                  |   1 +
>   docs/devel/qobject.rst                |  11 +++
>   include/hw/qdev-properties-system.h   |   2 +-
>   include/qapi/qmp/qlit.h               |  16 +++-
>   include/qapi/qmp/qnum.h               |  47 ++++++++++-
>   include/qapi/qmp/qobject.h            |  48 +++++++----
>   include/qom/field-property-internal.h |   4 -
>   include/qom/field-property.h          |  26 +++---
>   include/qom/object.h                  |  11 +++
>   include/qom/property-types.h          |  21 ++---
>   hw/core/qdev-properties-system.c      |   8 --
>   qobject/qlit.c                        |   4 +-
>   qobject/qnum.c                        | 116 +++++++++++++++-----------
>   qom/field-property.c                  |  27 ++++--
>   qom/object.c                          |   2 +-
>   qom/property-types.c                  |  36 ++------
>   tests/check-qjson.c                   |  72 ++++++++++++++--
>   17 files changed, 295 insertions(+), 157 deletions(-)
>   create mode 100644 docs/devel/qobject.rst
> 

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks,

Paolo



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/8] qom: Use qlit to represent property defaults
  2020-11-10 16:39 ` Paolo Bonzini
@ 2020-11-10 18:16   ` Eduardo Habkost
  0 siblings, 0 replies; 12+ messages in thread
From: Eduardo Habkost @ 2020-11-10 18:16 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Daniel P. Berrangé, qemu-devel, Markus Armbruster

On Tue, Nov 10, 2020 at 05:39:08PM +0100, Paolo Bonzini wrote:
> On 09/11/20 22:25, Eduardo Habkost wrote:
> > Based-on: 20201104160021.2342108-1-ehabkost@redhat.com
> > Git branch: https://gitlab.com/ehabkost/qemu/-/commits/work/qdev-qlit-defaults
> > 
> > This extend qlit.h to support all QNum types (signed int,
> > unsigned int, and double), and use QLitObject to represent field
> > property defaults.
> > 
> > It allows us to get rid of most type-specific .set_default_value
> > functions for QOM property types.
> > 
> > Eduardo Habkost (8):
> >    qobject: Include API docs in docs/devel/qobject.html
> >    qnum: Make qnum_get_double() get const pointer
> >    qnum: QNumValue type for QNum value literals
> >    qnum: qnum_value_is_equal() function
> >    qlit: Support all types of QNums
> >    qlit: qlit_type() function
> >    qom: Make object_property_set_default() public
> >    qom: Use qlit to represent property defaults
> > 
> >   docs/devel/index.rst                  |   1 +
> >   docs/devel/qobject.rst                |  11 +++
> >   include/hw/qdev-properties-system.h   |   2 +-
> >   include/qapi/qmp/qlit.h               |  16 +++-
> >   include/qapi/qmp/qnum.h               |  47 ++++++++++-
> >   include/qapi/qmp/qobject.h            |  48 +++++++----
> >   include/qom/field-property-internal.h |   4 -
> >   include/qom/field-property.h          |  26 +++---
> >   include/qom/object.h                  |  11 +++
> >   include/qom/property-types.h          |  21 ++---
> >   hw/core/qdev-properties-system.c      |   8 --
> >   qobject/qlit.c                        |   4 +-
> >   qobject/qnum.c                        | 116 +++++++++++++++-----------
> >   qom/field-property.c                  |  27 ++++--
> >   qom/object.c                          |   2 +-
> >   qom/property-types.c                  |  36 ++------
> >   tests/check-qjson.c                   |  72 ++++++++++++++--
> >   17 files changed, 295 insertions(+), 157 deletions(-)
> >   create mode 100644 docs/devel/qobject.rst
> > 
> 
> Acked-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks!

It looks like I broke some unit tests in this series.  I will
submit v2 after submitting v3 of the field property series.

-- 
Eduardo



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-11-10 18:18 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-09 21:25 [PATCH 0/8] qom: Use qlit to represent property defaults Eduardo Habkost
2020-11-09 21:25 ` [PATCH 1/8] qobject: Include API docs in docs/devel/qobject.html Eduardo Habkost
2020-11-09 21:25 ` [PATCH 2/8] qnum: Make qnum_get_double() get const pointer Eduardo Habkost
2020-11-09 21:25 ` [PATCH 3/8] qnum: QNumValue type for QNum value literals Eduardo Habkost
2020-11-09 21:25 ` [PATCH 4/8] qnum: qnum_value_is_equal() function Eduardo Habkost
2020-11-09 21:25 ` [PATCH 5/8] qlit: Support all types of QNums Eduardo Habkost
2020-11-09 21:25 ` [PATCH 6/8] qlit: qlit_type() function Eduardo Habkost
2020-11-09 21:25 ` [PATCH 7/8] qom: Make object_property_set_default() public Eduardo Habkost
2020-11-09 21:25 ` [PATCH 8/8] qom: Use qlit to represent property defaults Eduardo Habkost
2020-11-09 21:39 ` [PATCH 0/8] " no-reply
2020-11-10 16:39 ` Paolo Bonzini
2020-11-10 18:16   ` Eduardo Habkost

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.