aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/qapi.py63
1 files changed, 49 insertions, 14 deletions
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 868f08b593..6a339d60b5 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -32,6 +32,12 @@ builtin_types = {
'size': 'QTYPE_QINT',
}
+enum_types = []
+struct_types = []
+union_types = []
+events = []
+all_names = {}
+
def error_path(parent):
res = ""
while parent:
@@ -256,7 +262,14 @@ def discriminator_find_enum_define(expr):
return find_enum(discriminator_type)
def check_event(expr, expr_info):
+ global events
+ name = expr['event']
params = expr.get('data')
+
+ if name.upper() == 'MAX':
+ raise QAPIExprError(expr_info, "Event name 'MAX' cannot be created")
+ events.append(name)
+
if params:
for argname, argentry, optional, structured in parse_args(params):
if structured:
@@ -430,6 +443,9 @@ def check_keys(expr_elem, meta, required, optional=[]):
def parse_schema(input_file):
+ global all_names
+ exprs = []
+
# First pass: read entire file into memory
try:
schema = QAPISchema(open(input_file, "r"))
@@ -437,30 +453,34 @@ def parse_schema(input_file):
print >>sys.stderr, e
exit(1)
- exprs = []
-
try:
# Next pass: learn the types and check for valid expression keys. At
# this point, top-level 'include' has already been flattened.
+ for builtin in builtin_types.keys():
+ all_names[builtin] = 'built-in'
for expr_elem in schema.exprs:
expr = expr_elem['expr']
+ info = expr_elem['info']
if expr.has_key('enum'):
check_keys(expr_elem, 'enum', ['data'])
- add_enum(expr['enum'], expr['data'])
+ add_enum(expr['enum'], info, expr['data'])
elif expr.has_key('union'):
check_keys(expr_elem, 'union', ['data'],
['base', 'discriminator'])
- add_union(expr)
+ add_union(expr, info)
elif expr.has_key('alternate'):
check_keys(expr_elem, 'alternate', ['data'])
+ add_name(expr['alternate'], info, 'alternate')
elif expr.has_key('type'):
check_keys(expr_elem, 'type', ['data'], ['base'])
- add_struct(expr)
+ add_struct(expr, info)
elif expr.has_key('command'):
check_keys(expr_elem, 'command', [],
['data', 'returns', 'gen', 'success-response'])
+ add_name(expr['command'], info, 'command')
elif expr.has_key('event'):
check_keys(expr_elem, 'event', [], ['data'])
+ add_name(expr['event'], info, 'event')
else:
raise QAPIExprError(expr_elem['info'],
"Expression is missing metatype")
@@ -471,9 +491,11 @@ def parse_schema(input_file):
expr = expr_elem['expr']
if expr.has_key('union'):
if not discriminator_find_enum_define(expr):
- add_enum('%sKind' % expr['union'])
+ add_enum('%sKind' % expr['union'], expr_elem['info'],
+ implicit=True)
elif expr.has_key('alternate'):
- add_enum('%sKind' % expr['alternate'])
+ add_enum('%sKind' % expr['alternate'], expr_elem['info'],
+ implicit=True)
# Final pass - validate that exprs make sense
check_exprs(schema)
@@ -567,12 +589,22 @@ def type_name(name):
return c_list_type(name[0])
return name
-enum_types = []
-struct_types = []
-union_types = []
+def add_name(name, info, meta, implicit = False):
+ global all_names
+ if name in all_names:
+ raise QAPIExprError(info,
+ "%s '%s' is already defined"
+ % (all_names[name], name))
+ if not implicit and name[-4:] == 'Kind':
+ raise QAPIExprError(info,
+ "%s '%s' should not end in 'Kind'"
+ % (meta, name))
+ all_names[name] = meta
-def add_struct(definition):
+def add_struct(definition, info):
global struct_types
+ name = definition['type']
+ add_name(name, info, 'struct')
struct_types.append(definition)
def find_struct(name):
@@ -582,8 +614,10 @@ def find_struct(name):
return struct
return None
-def add_union(definition):
+def add_union(definition, info):
global union_types
+ name = definition['union']
+ add_name(name, info, 'union')
union_types.append(definition)
def find_union(name):
@@ -593,8 +627,9 @@ def find_union(name):
return union
return None
-def add_enum(name, enum_values = None):
+def add_enum(name, info, enum_values = None, implicit = False):
global enum_types
+ add_name(name, info, 'enum', implicit)
enum_types.append({"enum_name": name, "enum_values": enum_values})
def find_enum(name):
@@ -636,7 +671,7 @@ def c_type(name, is_param=False):
return name
elif name == None or len(name) == 0:
return 'void'
- elif name == name.upper():
+ elif name in events:
return '%sEvent *%s' % (camel_case(name), eatspace)
else:
return '%s *%s' % (name, eatspace)