cbd8acf3 | 28-Feb-2017 |
Daniel P. Berrange <berrange@redhat.com> |
qapi: qobject input visitor variant for use with keyval_parse()
Currently the QObjectInputVisitor assumes that all scalar values are directly represented as the final types declared by the thing bei
qapi: qobject input visitor variant for use with keyval_parse()
Currently the QObjectInputVisitor assumes that all scalar values are directly represented as the final types declared by the thing being visited. i.e. it assumes an 'int' is using QInt, and a 'bool' is using QBool, etc. This is good when QObjectInputVisitor is fed a QObject that came from a JSON document on the QMP monitor, as it will strictly validate correctness.
To allow QObjectInputVisitor to be reused for visiting a QObject originating from keyval_parse(), an alternative mode is needed where all the scalars types are represented as QString and converted on the fly to the final desired type.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Message-Id: <1475246744-29302-8-git-send-email-berrange@redhat.com>
Rebased, conflicts resolved, commit message updated to refer to keyval_parse(). autocast replaced by keyval in identifiers, noautocast replaced by fail in tests.
Fix qobject_input_type_uint64_keyval() not to reject '-', for QemuOpts compatibility: replace parse_uint_full() by open-coded parse_option_number(). The next commit will add suitable tests. Leave out the fancy ERANGE error reporting for now, but add a TODO comment. Add it qobject_input_type_int64_keyval() and qobject_input_type_number_keyval(), too.
Open code parse_option_bool() and parse_option_size() so we have to call qobject_input_get_name() only when actually needed. Again, leave out ERANGE error reporting for now.
QAPI/QMP downstream extension prefixes __RFQDN_ don't work, because keyval_parse() splits them at '.'. This will be addressed later in the series.
qobject_input_type_int64_keyval(), qobject_input_type_uint64_keyval(), qobject_input_type_number_keyval() tweaked for style.
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <1488317230-26248-5-git-send-email-armbru@redhat.com>
show more ...
|
a4a1c70d | 03-Mar-2017 |
Markus Armbruster <armbru@redhat.com> |
qapi: Make input visitors detect unvisited list tails
Fix the design flaw demonstrated in the previous commit: new method check_list() lets input visitors report that unvisited input remains for a l
qapi: Make input visitors detect unvisited list tails
Fix the design flaw demonstrated in the previous commit: new method check_list() lets input visitors report that unvisited input remains for a list, exactly like check_struct() lets them report that unvisited input remains for a struct or union.
Implement the method for the qobject input visitor (straightforward), and the string input visitor (less so, due to the magic list syntax there). The opts visitor's list magic is even more impenetrable, and all I can do there today is a stub with a FIXME comment. No worse than before.
Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <1488544368-30622-26-git-send-email-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
show more ...
|
a8aec6de | 03-Mar-2017 |
Markus Armbruster <armbru@redhat.com> |
qapi: Drop string input visitor method optional()
visit_optional() is to be called only between visit_start_struct() and visit_end_struct(). Visitors that don't support struct visits, i.e. don't im
qapi: Drop string input visitor method optional()
visit_optional() is to be called only between visit_start_struct() and visit_end_struct(). Visitors that don't support struct visits, i.e. don't implement start_struct(), end_struct(), have no use for it. Clarify documentation.
The string input visitor doesn't support struct visits. Its parse_optional() is therefore useless. Drop it.
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <1488544368-30622-16-git-send-email-armbru@redhat.com>
show more ...
|
a9fc37f6 | 03-Mar-2017 |
Markus Armbruster <armbru@redhat.com> |
qapi: Improve qobject input visitor error reporting
Error messages refer to nodes of the QObject being visited by name. Trouble is the names are sometimes less than helpful:
* The name of the root
qapi: Improve qobject input visitor error reporting
Error messages refer to nodes of the QObject being visited by name. Trouble is the names are sometimes less than helpful:
* The name of the root QObject is whatever @name argument got passed to the visitor, except NULL gets mapped to "null". We commonly pass NULL. Not good.
Avoiding errors "at the root" mitigates. For instance, visit_start_struct() can only fail when the visited object is not a dictionary, and we commonly ensure it is beforehand.
* The name of a QDict's member is the member key. Good enough only when this happens to be unique.
* The name of a QList's member is "null". Not good.
Improve error messages by referring to nodes by path instead, as follows:
* The path of the root QObject is whatever @name argument got passed to the visitor, except NULL gets mapped to "<anonymous>".
* The path of a root QDict's member is the member key.
* The path of a root QList's member is "[%u]", where %u is the list index, starting at zero.
* The path of a non-root QDict's member is the path of the QDict concatenated with "." and the member key.
* The path of a non-root QList's member is the path of the QList concatenated with "[%u]", where %u is the list index.
For example, the incorrect QMP command
{ "execute": "blockdev-add", "arguments": { "node-name": "foo", "driver": "raw", "file": {"driver": "file" } } }
now fails with
{"error": {"class": "GenericError", "desc": "Parameter 'file.filename' is missing"}}
instead of
{"error": {"class": "GenericError", "desc": "Parameter 'filename' is missing"}}
and
{ "execute": "input-send-event", "arguments": { "device": "bar", "events": [ [] ] } }
now fails with
{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'events[0]', expected: object"}}
instead of
{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'null', expected: QDict"}}
Aside: calling the thing "parameter" is suboptimal for QMP, because the root object is "arguments" there.
The qobject output visitor doesn't have this problem because it should not fail. Same for dealloc and clone visitors.
The string visitors don't have this problem because they visit just one value, whose name needs to be passed to the visitor as @name. The string output visitor shouldn't fail anyway.
The options visitor uses QemuOpts names. Their name space is flat, so the use of QDict member keys as names is fine. NULL names used with roots and lists could conceivably result in bad error messages. Left for another day.
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <1488544368-30622-15-git-send-email-armbru@redhat.com>
show more ...
|
99fb0c53 | 03-Mar-2017 |
Markus Armbruster <armbru@redhat.com> |
qmp: Eliminate silly QERR_QMP_* macros
The QERR_ macros are leftovers from the days of "rich" error objects.
QERR_QMP_BAD_INPUT_OBJECT, QERR_QMP_BAD_INPUT_OBJECT_MEMBER, QERR_QMP_EXTRA_MEMBER are u
qmp: Eliminate silly QERR_QMP_* macros
The QERR_ macros are leftovers from the days of "rich" error objects.
QERR_QMP_BAD_INPUT_OBJECT, QERR_QMP_BAD_INPUT_OBJECT_MEMBER, QERR_QMP_EXTRA_MEMBER are used in just one place now, except for one use that has crept into qobject-input-visitor.c.
Drop these macros, to make the (bad) error messages more visible.
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <1488544368-30622-10-git-send-email-armbru@redhat.com>
show more ...
|
603476c2 | 30-Sep-2016 |
Daniel P. Berrange <berrange@redhat.com> |
qdict: implement a qdict_crumple method for un-flattening a dict
The qdict_flatten() method will take a dict whose elements are further nested dicts/lists and flatten them by concatenating keys.
Th
qdict: implement a qdict_crumple method for un-flattening a dict
The qdict_flatten() method will take a dict whose elements are further nested dicts/lists and flatten them by concatenating keys.
The qdict_crumple() method aims to do the reverse, taking a flat qdict, and turning it into a set of nested dicts/lists. It will apply nesting based on the key name, with a '.' indicating a new level in the hierarchy. If the keys in the nested structure are all numeric, it will create a list, otherwise it will create a dict.
If the keys are a mixture of numeric and non-numeric, or the numeric keys are not in strictly ascending order, an error will be reported.
As an example, a flat dict containing
{ 'foo.0.bar': 'one', 'foo.0.wizz': '1', 'foo.1.bar': 'two', 'foo.1.wizz': '2' }
will get turned into a dict with one element 'foo' whose value is a list. The list elements will each in turn be dicts.
{ 'foo': [ { 'bar': 'one', 'wizz': '1' }, { 'bar': 'two', 'wizz': '2' } ], }
If the key is intended to contain a literal '.', then it must be escaped as '..'. ie a flat dict
{ 'foo..bar': 'wizz', 'bar.foo..bar': 'eek', 'bar.hello': 'world' }
Will end up as
{ 'foo.bar': 'wizz', 'bar': { 'foo.bar': 'eek', 'hello': 'world' } }
The intent of this function is that it allows a set of QemuOpts to be turned into a nested data structure that mirrors the nesting used when the same object is defined over QMP.
Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Message-Id: <1475246744-29302-3-git-send-email-berrange@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Parameter recursive dropped along with its tests; whitespace style touched up] Signed-off-by: Markus Armbruster <armbru@redhat.com>
show more ...
|
09e68369 | 30-Sep-2016 |
Daniel P. Berrange <berrange@redhat.com> |
qapi: rename QmpInputVisitor to QObjectInputVisitor
The QmpInputVisitor has no direct dependency on QMP. It is valid to use it anywhere that one has a QObject. Rename it to better reflect its functi
qapi: rename QmpInputVisitor to QObjectInputVisitor
The QmpInputVisitor has no direct dependency on QMP. It is valid to use it anywhere that one has a QObject. Rename it to better reflect its functionality as a generic QObject to QAPI converter.
The previous commit renamed the files, this one renames C identifiers.
Reviewed-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Message-Id: <1475246744-29302-5-git-send-email-berrange@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Straightforwardly rebased, split into file and identifier rename] Signed-off-by: Markus Armbruster <armbru@redhat.com>
show more ...
|