summaryrefslogtreecommitdiff
path: root/qapi/qobject-input-visitor.c
AgeCommit message (Collapse)AuthorFilesLines
2017-07-24qapi: Use QNull for a more regular visit_type_null()Markus Armbruster1-1/+5
Make visit_type_null() take an @obj argument like its buddies. This helps keep the next commit simple. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
2017-06-20qapi: update the qobject visitor to use QNUM_U64Marc-André Lureau1-5/+16
Switch to use QNum/uint where appropriate to remove i64 limitation. The input visitor will cast i64 input to u64 for compatibility reasons (existing json QMP client already use negative i64 for large u64, and expect an implicit cast in qemu). Note: before the patch, uint64_t values above INT64_MAX are sent over json QMP as negative values, e.g. UINT64_MAX is sent as -1. After the patch, they are sent unmodified. Clearly a bug fix, but we have to consider compatibility issues anyway. libvirt should cope fine, because its parsing of unsigned integers accepts negative values modulo 2^64. There's hope that other clients will, too. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20170607163635.17635-12-marcandre.lureau@redhat.com> [check_native_list() tweaked for consistency with signed case] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-06-20qapi: Remove visit_start_alternate() parameter promote_intMarc-André Lureau1-1/+1
Before the previous commit, parameter promote_int = true made visit_start_alternate() with an input visitor avoid QTYPE_QINT variants and create QTYPE_QFLOAT variants instead. This was used where QTYPE_QINT variants were invalid. The previous commit fused QTYPE_QINT with QTYPE_QFLOAT, rendering promote_int useless and unused. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20170607163635.17635-8-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-06-20qapi: merge QInt and QFloat in QNumMarc-André Lureau1-28/+13
We would like to use a same QObject type to represent numbers, whether they are int, uint, or floats. Getters will allow some compatibility between the various types if the number fits other representations. Add a few more tests while at it. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20170607163635.17635-7-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [parse_stats_intervals() simplified a bit, comment in test_visitor_in_int_overflow() tidied up, suppress bogus warnings] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-06-19qapi: Clean up qobject_input_type_number() control flowMarc-André Lureau1-4/+4
Use the more common pattern to error out. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20170607163635.17635-6-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Commit message tweaked] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-31qobject-input-visitor: Reject non-finite numbers with keyvalMarkus Armbruster1-1/+2
The QObject input visitor can produce only finite numbers when its input comes out of the JSON parser, because the the JSON parser implements RFC 7159, which provides no syntax for infinity and NaN. However, it can produce infinity and NaN when its input comes out of keyval_parse(), because we parse with strtod() then. The keyval variant should not be able to express things the JSON variant can't. Rejecting non-finite numbers there is the conservative fix. It's also minimally invasive. We could instead extend our JSON dialect to provide for infinity and NaN. Not today. Note that the JSON formatter can emit non-finite numbers (marked FIXME in commit 6e8e5cb). Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <1495471335-23707-2-git-send-email-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2017-05-09qobject-input-visitor: Catch misuse of end_struct vs. end_listMarkus Armbruster1-2/+19
Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <1493282486-28338-5-git-send-email-armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> [More elaborate assertions for clarity]
2017-05-09qobject-input-visitor: Document full_name_nth()Markus Armbruster1-0/+11
Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <1493282486-28338-3-git-send-email-armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2017-03-07keyval: Support listsMarkus Armbruster1-1/+5
Additionally permit non-negative integers as key components. A dictionary's keys must either be all integers or none. If all keys are integers, convert the dictionary to a list. The set of keys must be [0,N]. Examples: * list.1=goner,list.0=null,list.1=eins,list.2=zwei is equivalent to JSON [ "null", "eins", "zwei" ] * a.b.c=1,a.b.0=2 is inconsistent: a.b.c clashes with a.b.0 * list.0=null,list.2=eins,list.2=zwei has a hole: list.1 is missing Similar design flaw as for objects: there is no way to denote an empty list. While interpreting "key absent" as empty list seems natural (removing a list member from the input string works when there are multiple ones, so why not when there's just one), it doesn't work: "key absent" already means "optional list absent", which isn't the same as "empty list present". Update the keyval object visitor to use this a.0 syntax in error messages rather than the usual a[0]. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <1488317230-26248-25-git-send-email-armbru@redhat.com> [Off-by-one fix squashed in, as per Kevin's review] Reviewed-by: Kevin Wolf <kwolf@redhat.com>
2017-03-07qapi: Improve how keyval input visitor reports unexpected dictsMarkus Armbruster1-4/+22
Incorrect option -blockdev node-name=foo,driver=file,filename=foo.img,aio.unmap=on is rejected with "Invalid parameter type for 'aio', expected: string". To make sense of this, you almost have to translate it into the equivalent QMP command { "execute": "blockdev-add", "arguments": { "node-name": "foo", "driver": "file", "filename": "foo.img", "aio": { "unmap": true } } } Improve the error message to "Parameters 'aio.*' are unexpected". Take care not to confuse the case "unexpected nested parameters" (i.e. the object is a QDict or QList) with the case "non-string scalar parameter". The latter is a misuse of the visitor, and should perhaps be an assertion. Note that test-qobject-input-visitor exercises this misuse in test_visitor_in_int_keyval(), test_visitor_in_bool_keyval() and test_visitor_in_number_keyval(). Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <1488317230-26248-23-git-send-email-armbru@redhat.com>
2017-03-07qapi: New qobject_input_visitor_new_str() for convenienceMarkus Armbruster1-0/+36
Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <1488317230-26248-21-git-send-email-armbru@redhat.com>
2017-03-07qapi: Factor out common qobject_input_get_keyval()Markus Armbruster1-52/+35
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <1488317230-26248-8-git-send-email-armbru@redhat.com>
2017-03-07qapi: Factor out common part of qobject input visitor creationMarkus Armbruster1-25/+16
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <1488317230-26248-7-git-send-email-armbru@redhat.com>
2017-03-07qapi: qobject input visitor variant for use with keyval_parse()Daniel P. Berrange1-1/+165
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>
2017-03-05qapi: Fix object input visit beyond end of listMarkus Armbruster1-3/+8
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <1488544368-30622-28-git-send-email-armbru@redhat.com>
2017-03-05qapi: Make input visitors detect unvisited list tailsMarkus Armbruster1-6/+31
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>
2017-03-05qapi: Drop unused non-strict qobject input visitorMarkus Armbruster1-19/+11
The split between tests/test-qobject-input-visitor.c and tests/test-qobject-input-strict.c now makes less sense than ever. The next commit will take care of that. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <1488544368-30622-20-git-send-email-armbru@redhat.com>
2017-03-05qapi: Improve qobject input visitor error reportingMarkus Armbruster1-34/+87
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>
2017-03-05qapi: Make QObject input visitor set *list reliablyMarkus Armbruster1-9/+5
qobject_input_start_struct() sets *list, except when it fails because qobject_input_get_object() fails, i.e. the input object doesn't exist. All the other input visitor start_struct(), start_list(), start_alternate() always set *obj / *list. Change qobject_input_start_struct() to match. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <1488544368-30622-14-git-send-email-armbru@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2017-03-05qapi: Clean up after commit 3d344c2Markus Armbruster1-11/+3
Drop unused QIV_STACK_SIZE and unused qobject_input_start_struct() parameter errp. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <1488544368-30622-13-git-send-email-armbru@redhat.com>
2017-03-05qapi: Improve a QObject input visitor error messageMarkus Armbruster1-2/+1
The QObject input visitor has three error message formats: * Parameter '%s' is missing * "Invalid parameter type for '%s', expected: %s" * "QMP input object member '%s' is unexpected" The '%s' are member names (or "null", but I'll fix that later). The last error message calls the thing "QMP input object member" instead of "parameter". Misleading when the visitor is used on QObjects that don't come from QMP. Change it to "Parameter '%s' is unexpected". Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <1488544368-30622-12-git-send-email-armbru@redhat.com>
2017-03-05qmp: Eliminate silly QERR_QMP_* macrosMarkus Armbruster1-1/+2
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>
2016-10-25qapi: rename QmpInputVisitor to QObjectInputVisitorDaniel P. Berrange1-83/+85
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>
2016-10-25qapi: rename *qmp-*-visitor* to *qobject-*-visitor*Daniel P. Berrange1-0/+455
The QMP visitors have no direct dependency on QMP. It is valid to use them anywhere that one has a QObject. Rename them to better reflect their functionality as a generic QObject to QAPI converter. This is the first of three parts: rename the files. The next two parts will rename C identifiers. The split is necessary to make git rename detection work. Reviewed-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Split into file and identifier rename, two comments touched up] Signed-off-by: Markus Armbruster <armbru@redhat.com>