mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2017-05-31' into staging
QAPI patches for 2017-05-31 # gpg: Signature made Wed 31 May 2017 18:06:39 BST # gpg: using RSA key 0x3870B400EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-qapi-2017-05-31: qapi: Reject alternates that can't work with keyval_parse() tests/qapi-schema: Avoid 'str' in alternate test cases qapi: Document visit_type_any() issues with keyval input qobject-input-visitor: Reject non-finite numbers with keyval Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -607,6 +607,10 @@ void visit_type_number(Visitor *v, const char *name, double *obj,
|
||||
* @obj must be non-NULL. Input visitors set *@obj to the value;
|
||||
* other visitors will leave *@obj unchanged. *@obj must be non-NULL
|
||||
* for output visitors.
|
||||
*
|
||||
* Note that some kinds of input can't express arbitrary QObject.
|
||||
* E.g. the visitor returned by qobject_input_visitor_new_keyval()
|
||||
* can't create numbers or booleans, only strings.
|
||||
*/
|
||||
void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp);
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include <math.h>
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qobject-input-visitor.h"
|
||||
#include "qapi/visitor-impl.h"
|
||||
@@ -568,7 +569,7 @@ static void qobject_input_type_number_keyval(Visitor *v, const char *name,
|
||||
|
||||
errno = 0;
|
||||
*obj = strtod(str, &endp);
|
||||
if (errno || endp == str || *endp) {
|
||||
if (errno || endp == str || *endp || !isfinite(*obj)) {
|
||||
/* TODO report -ERANGE more nicely */
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
|
||||
full_name(qiv, name), "number");
|
||||
|
||||
+17
-2
@@ -812,11 +812,26 @@ def check_alternate(expr, info):
|
||||
if not qtype:
|
||||
raise QAPISemError(info, "Alternate '%s' member '%s' cannot use "
|
||||
"type '%s'" % (name, key, value))
|
||||
if qtype in types_seen:
|
||||
conflicting = set([qtype])
|
||||
if qtype == 'QTYPE_QSTRING':
|
||||
enum_expr = enum_types.get(value)
|
||||
if enum_expr:
|
||||
for v in enum_expr['data']:
|
||||
if v in ['on', 'off']:
|
||||
conflicting.add('QTYPE_QBOOL')
|
||||
if re.match(r'[-+0-9.]', v): # lazy, could be tightened
|
||||
conflicting.add('QTYPE_QINT')
|
||||
conflicting.add('QTYPE_QFLOAT')
|
||||
else:
|
||||
conflicting.add('QTYPE_QINT')
|
||||
conflicting.add('QTYPE_QFLOAT')
|
||||
conflicting.add('QTYPE_QBOOL')
|
||||
if conflicting & set(types_seen):
|
||||
raise QAPISemError(info, "Alternate '%s' member '%s' can't "
|
||||
"be distinguished from member '%s'"
|
||||
% (name, key, types_seen[qtype]))
|
||||
types_seen[qtype] = key
|
||||
for qt in conflicting:
|
||||
types_seen[qt] = key
|
||||
|
||||
|
||||
def check_enum(expr, info):
|
||||
|
||||
@@ -342,6 +342,8 @@ qapi-schema += alternate-array.json
|
||||
qapi-schema += alternate-base.json
|
||||
qapi-schema += alternate-clash.json
|
||||
qapi-schema += alternate-conflict-dict.json
|
||||
qapi-schema += alternate-conflict-enum-bool.json
|
||||
qapi-schema += alternate-conflict-enum-int.json
|
||||
qapi-schema += alternate-conflict-string.json
|
||||
qapi-schema += alternate-empty.json
|
||||
qapi-schema += alternate-nested.json
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
# the implicit Alt1Kind enum, we would still have a collision with the
|
||||
# resulting C union trying to have two members named 'a_b'.
|
||||
{ 'alternate': 'Alt1',
|
||||
'data': { 'a-b': 'str', 'a_b': 'int' } }
|
||||
'data': { 'a-b': 'bool', 'a_b': 'int' } }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# we reject alternates with multiple object branches
|
||||
# alternate branches of object type conflict with each other
|
||||
{ 'struct': 'One',
|
||||
'data': { 'name': 'str' } }
|
||||
{ 'struct': 'Two',
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
tests/qapi-schema/alternate-conflict-enum-bool.json:4: Alternate 'Alt' member 'two' can't be distinguished from member 'one'
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,6 @@
|
||||
# alternate branch of 'enum' type that conflicts with bool
|
||||
{ 'enum': 'Enum',
|
||||
'data': [ 'aus', 'off' ] }
|
||||
{ 'alternate': 'Alt',
|
||||
'data': { 'one': 'Enum',
|
||||
'two': 'bool' } }
|
||||
@@ -0,0 +1 @@
|
||||
tests/qapi-schema/alternate-conflict-enum-int.json:4: Alternate 'Alt' member 'two' can't be distinguished from member 'one'
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,6 @@
|
||||
# alternate branches of 'enum' type that conflicts with numbers
|
||||
{ 'enum': 'Enum',
|
||||
'data': [ '1', '2', '3' ] }
|
||||
{ 'alternate': 'Alt',
|
||||
'data': { 'one': 'Enum',
|
||||
'two': 'int' } }
|
||||
@@ -1 +1 @@
|
||||
tests/qapi-schema/alternate-conflict-string.json:4: Alternate 'Alt' member 'two' can't be distinguished from member 'one'
|
||||
tests/qapi-schema/alternate-conflict-string.json:2: Alternate 'Alt' member 'two' can't be distinguished from member 'one'
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# we reject alternates with multiple string-like branches
|
||||
{ 'enum': 'Enum',
|
||||
'data': [ 'hello', 'world' ] }
|
||||
# alternate branches of 'str' type conflict with all scalar types
|
||||
{ 'alternate': 'Alt',
|
||||
'data': { 'one': 'str',
|
||||
'two': 'Enum' } }
|
||||
'two': 'int' } }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# we reject a nested alternate branch
|
||||
{ 'alternate': 'Alt1',
|
||||
'data': { 'name': 'str', 'value': 'int' } }
|
||||
'data': { 'name': 'bool', 'value': 'int' } }
|
||||
{ 'alternate': 'Alt2',
|
||||
'data': { 'nested': 'Alt1', 'b': 'bool' } }
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# we do not allow alternate arguments
|
||||
{ 'alternate': 'Alt', 'data': { 'case1': 'int', 'case2': 'str' } }
|
||||
{ 'alternate': 'Alt', 'data': { 'case1': 'int', 'case2': 'bool' } }
|
||||
{ 'command': 'oops', 'data': 'Alt' }
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
# @bb: b
|
||||
##
|
||||
{ 'alternate': 'AorB',
|
||||
'data': { 'a': 'str', 'b': 'int' } }
|
||||
'data': { 'a': 'bool', 'b': 'int' } }
|
||||
|
||||
@@ -93,19 +93,22 @@
|
||||
{ 'struct': 'WrapAlternate',
|
||||
'data': { 'alt': 'UserDefAlternate' } }
|
||||
{ 'alternate': 'UserDefAlternate',
|
||||
'data': { 'udfu': 'UserDefFlatUnion', 's': 'str', 'i': 'int' } }
|
||||
'data': { 'udfu': 'UserDefFlatUnion', 'e': 'EnumOne', 'i': 'int' } }
|
||||
|
||||
{ 'struct': 'UserDefC',
|
||||
'data': { 'string1': 'str', 'string2': 'str' } }
|
||||
|
||||
# for testing use of 'number' within alternates
|
||||
{ 'alternate': 'AltStrBool', 'data': { 's': 'str', 'b': 'bool' } }
|
||||
{ 'alternate': 'AltStrNum', 'data': { 's': 'str', 'n': 'number' } }
|
||||
{ 'alternate': 'AltNumStr', 'data': { 'n': 'number', 's': 'str' } }
|
||||
{ 'alternate': 'AltStrInt', 'data': { 's': 'str', 'i': 'int' } }
|
||||
{ 'alternate': 'AltEnumBool', 'data': { 'e': 'EnumOne', 'b': 'bool' } }
|
||||
{ 'alternate': 'AltEnumNum', 'data': { 'e': 'EnumOne', 'n': 'number' } }
|
||||
{ 'alternate': 'AltNumEnum', 'data': { 'n': 'number', 'e': 'EnumOne' } }
|
||||
{ 'alternate': 'AltEnumInt', 'data': { 'e': 'EnumOne', 'i': 'int' } }
|
||||
{ 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } }
|
||||
{ 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } }
|
||||
|
||||
# for testing use of 'str' within alternates
|
||||
{ 'alternate': 'AltStrObj', 'data': { 's': 'str', 'o': 'TestStruct' } }
|
||||
|
||||
# for testing native lists
|
||||
{ 'union': 'UserDefNativeListUnion',
|
||||
'data': { 'integer': ['int'],
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user