These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / scripts / qapi.py
1 #
2 # QAPI helper library
3 #
4 # Copyright IBM, Corp. 2011
5 # Copyright (c) 2013-2016 Red Hat Inc.
6 #
7 # Authors:
8 #  Anthony Liguori <aliguori@us.ibm.com>
9 #  Markus Armbruster <armbru@redhat.com>
10 #
11 # This work is licensed under the terms of the GNU GPL, version 2.
12 # See the COPYING file in the top-level directory.
13
14 import re
15 from ordereddict import OrderedDict
16 import errno
17 import getopt
18 import os
19 import sys
20 import string
21
22 builtin_types = {
23     'str':      'QTYPE_QSTRING',
24     'int':      'QTYPE_QINT',
25     'number':   'QTYPE_QFLOAT',
26     'bool':     'QTYPE_QBOOL',
27     'int8':     'QTYPE_QINT',
28     'int16':    'QTYPE_QINT',
29     'int32':    'QTYPE_QINT',
30     'int64':    'QTYPE_QINT',
31     'uint8':    'QTYPE_QINT',
32     'uint16':   'QTYPE_QINT',
33     'uint32':   'QTYPE_QINT',
34     'uint64':   'QTYPE_QINT',
35     'size':     'QTYPE_QINT',
36     'any':      None,           # any QType possible, actually
37     'QType':    'QTYPE_QSTRING',
38 }
39
40 # Whitelist of commands allowed to return a non-dictionary
41 returns_whitelist = [
42     # From QMP:
43     'human-monitor-command',
44     'qom-get',
45     'query-migrate-cache-size',
46     'query-tpm-models',
47     'query-tpm-types',
48     'ringbuf-read',
49
50     # From QGA:
51     'guest-file-open',
52     'guest-fsfreeze-freeze',
53     'guest-fsfreeze-freeze-list',
54     'guest-fsfreeze-status',
55     'guest-fsfreeze-thaw',
56     'guest-get-time',
57     'guest-set-vcpus',
58     'guest-sync',
59     'guest-sync-delimited',
60 ]
61
62 # Whitelist of entities allowed to violate case conventions
63 case_whitelist = [
64     # From QMP:
65     'ACPISlotType',         # DIMM, visible through query-acpi-ospm-status
66     'CpuInfoMIPS',          # PC, visible through query-cpu
67     'CpuInfoTricore',       # PC, visible through query-cpu
68     'QapiErrorClass',       # all members, visible through errors
69     'UuidInfo',             # UUID, visible through query-uuid
70     'X86CPURegister32',     # all members, visible indirectly through qom-get
71     'q_obj_CpuInfo-base',   # CPU, visible through query-cpu
72 ]
73
74 enum_types = []
75 struct_types = []
76 union_types = []
77 events = []
78 all_names = {}
79
80 #
81 # Parsing the schema into expressions
82 #
83
84
85 def error_path(parent):
86     res = ""
87     while parent:
88         res = ("In file included from %s:%d:\n" % (parent['file'],
89                                                    parent['line'])) + res
90         parent = parent['parent']
91     return res
92
93
94 class QAPISchemaError(Exception):
95     def __init__(self, schema, msg):
96         Exception.__init__(self)
97         self.fname = schema.fname
98         self.msg = msg
99         self.col = 1
100         self.line = schema.line
101         for ch in schema.src[schema.line_pos:schema.pos]:
102             if ch == '\t':
103                 self.col = (self.col + 7) % 8 + 1
104             else:
105                 self.col += 1
106         self.info = schema.incl_info
107
108     def __str__(self):
109         return error_path(self.info) + \
110             "%s:%d:%d: %s" % (self.fname, self.line, self.col, self.msg)
111
112
113 class QAPIExprError(Exception):
114     def __init__(self, expr_info, msg):
115         Exception.__init__(self)
116         assert expr_info
117         self.info = expr_info
118         self.msg = msg
119
120     def __str__(self):
121         return error_path(self.info['parent']) + \
122             "%s:%d: %s" % (self.info['file'], self.info['line'], self.msg)
123
124
125 class QAPISchemaParser(object):
126
127     def __init__(self, fp, previously_included=[], incl_info=None):
128         abs_fname = os.path.abspath(fp.name)
129         fname = fp.name
130         self.fname = fname
131         previously_included.append(abs_fname)
132         self.incl_info = incl_info
133         self.src = fp.read()
134         if self.src == '' or self.src[-1] != '\n':
135             self.src += '\n'
136         self.cursor = 0
137         self.line = 1
138         self.line_pos = 0
139         self.exprs = []
140         self.accept()
141
142         while self.tok is not None:
143             expr_info = {'file': fname, 'line': self.line,
144                          'parent': self.incl_info}
145             expr = self.get_expr(False)
146             if isinstance(expr, dict) and "include" in expr:
147                 if len(expr) != 1:
148                     raise QAPIExprError(expr_info,
149                                         "Invalid 'include' directive")
150                 include = expr["include"]
151                 if not isinstance(include, str):
152                     raise QAPIExprError(expr_info,
153                                         "Value of 'include' must be a string")
154                 incl_abs_fname = os.path.join(os.path.dirname(abs_fname),
155                                               include)
156                 # catch inclusion cycle
157                 inf = expr_info
158                 while inf:
159                     if incl_abs_fname == os.path.abspath(inf['file']):
160                         raise QAPIExprError(expr_info, "Inclusion loop for %s"
161                                             % include)
162                     inf = inf['parent']
163                 # skip multiple include of the same file
164                 if incl_abs_fname in previously_included:
165                     continue
166                 try:
167                     fobj = open(incl_abs_fname, 'r')
168                 except IOError as e:
169                     raise QAPIExprError(expr_info,
170                                         '%s: %s' % (e.strerror, include))
171                 exprs_include = QAPISchemaParser(fobj, previously_included,
172                                                  expr_info)
173                 self.exprs.extend(exprs_include.exprs)
174             else:
175                 expr_elem = {'expr': expr,
176                              'info': expr_info}
177                 self.exprs.append(expr_elem)
178
179     def accept(self):
180         while True:
181             self.tok = self.src[self.cursor]
182             self.pos = self.cursor
183             self.cursor += 1
184             self.val = None
185
186             if self.tok == '#':
187                 self.cursor = self.src.find('\n', self.cursor)
188             elif self.tok in "{}:,[]":
189                 return
190             elif self.tok == "'":
191                 string = ''
192                 esc = False
193                 while True:
194                     ch = self.src[self.cursor]
195                     self.cursor += 1
196                     if ch == '\n':
197                         raise QAPISchemaError(self,
198                                               'Missing terminating "\'"')
199                     if esc:
200                         if ch == 'b':
201                             string += '\b'
202                         elif ch == 'f':
203                             string += '\f'
204                         elif ch == 'n':
205                             string += '\n'
206                         elif ch == 'r':
207                             string += '\r'
208                         elif ch == 't':
209                             string += '\t'
210                         elif ch == 'u':
211                             value = 0
212                             for _ in range(0, 4):
213                                 ch = self.src[self.cursor]
214                                 self.cursor += 1
215                                 if ch not in "0123456789abcdefABCDEF":
216                                     raise QAPISchemaError(self,
217                                                           '\\u escape needs 4 '
218                                                           'hex digits')
219                                 value = (value << 4) + int(ch, 16)
220                             # If Python 2 and 3 didn't disagree so much on
221                             # how to handle Unicode, then we could allow
222                             # Unicode string defaults.  But most of QAPI is
223                             # ASCII-only, so we aren't losing much for now.
224                             if not value or value > 0x7f:
225                                 raise QAPISchemaError(self,
226                                                       'For now, \\u escape '
227                                                       'only supports non-zero '
228                                                       'values up to \\u007f')
229                             string += chr(value)
230                         elif ch in "\\/'\"":
231                             string += ch
232                         else:
233                             raise QAPISchemaError(self,
234                                                   "Unknown escape \\%s" % ch)
235                         esc = False
236                     elif ch == "\\":
237                         esc = True
238                     elif ch == "'":
239                         self.val = string
240                         return
241                     else:
242                         string += ch
243             elif self.src.startswith("true", self.pos):
244                 self.val = True
245                 self.cursor += 3
246                 return
247             elif self.src.startswith("false", self.pos):
248                 self.val = False
249                 self.cursor += 4
250                 return
251             elif self.src.startswith("null", self.pos):
252                 self.val = None
253                 self.cursor += 3
254                 return
255             elif self.tok == '\n':
256                 if self.cursor == len(self.src):
257                     self.tok = None
258                     return
259                 self.line += 1
260                 self.line_pos = self.cursor
261             elif not self.tok.isspace():
262                 raise QAPISchemaError(self, 'Stray "%s"' % self.tok)
263
264     def get_members(self):
265         expr = OrderedDict()
266         if self.tok == '}':
267             self.accept()
268             return expr
269         if self.tok != "'":
270             raise QAPISchemaError(self, 'Expected string or "}"')
271         while True:
272             key = self.val
273             self.accept()
274             if self.tok != ':':
275                 raise QAPISchemaError(self, 'Expected ":"')
276             self.accept()
277             if key in expr:
278                 raise QAPISchemaError(self, 'Duplicate key "%s"' % key)
279             expr[key] = self.get_expr(True)
280             if self.tok == '}':
281                 self.accept()
282                 return expr
283             if self.tok != ',':
284                 raise QAPISchemaError(self, 'Expected "," or "}"')
285             self.accept()
286             if self.tok != "'":
287                 raise QAPISchemaError(self, 'Expected string')
288
289     def get_values(self):
290         expr = []
291         if self.tok == ']':
292             self.accept()
293             return expr
294         if self.tok not in "{['tfn":
295             raise QAPISchemaError(self, 'Expected "{", "[", "]", string, '
296                                   'boolean or "null"')
297         while True:
298             expr.append(self.get_expr(True))
299             if self.tok == ']':
300                 self.accept()
301                 return expr
302             if self.tok != ',':
303                 raise QAPISchemaError(self, 'Expected "," or "]"')
304             self.accept()
305
306     def get_expr(self, nested):
307         if self.tok != '{' and not nested:
308             raise QAPISchemaError(self, 'Expected "{"')
309         if self.tok == '{':
310             self.accept()
311             expr = self.get_members()
312         elif self.tok == '[':
313             self.accept()
314             expr = self.get_values()
315         elif self.tok in "'tfn":
316             expr = self.val
317             self.accept()
318         else:
319             raise QAPISchemaError(self, 'Expected "{", "[" or string')
320         return expr
321
322 #
323 # Semantic analysis of schema expressions
324 # TODO fold into QAPISchema
325 # TODO catching name collisions in generated code would be nice
326 #
327
328
329 def find_base_members(base):
330     if isinstance(base, dict):
331         return base
332     base_struct_define = find_struct(base)
333     if not base_struct_define:
334         return None
335     return base_struct_define['data']
336
337
338 # Return the qtype of an alternate branch, or None on error.
339 def find_alternate_member_qtype(qapi_type):
340     if qapi_type in builtin_types:
341         return builtin_types[qapi_type]
342     elif find_struct(qapi_type):
343         return "QTYPE_QDICT"
344     elif find_enum(qapi_type):
345         return "QTYPE_QSTRING"
346     elif find_union(qapi_type):
347         return "QTYPE_QDICT"
348     return None
349
350
351 # Return the discriminator enum define if discriminator is specified as an
352 # enum type, otherwise return None.
353 def discriminator_find_enum_define(expr):
354     base = expr.get('base')
355     discriminator = expr.get('discriminator')
356
357     if not (discriminator and base):
358         return None
359
360     base_members = find_base_members(base)
361     if not base_members:
362         return None
363
364     discriminator_type = base_members.get(discriminator)
365     if not discriminator_type:
366         return None
367
368     return find_enum(discriminator_type)
369
370
371 # Names must be letters, numbers, -, and _.  They must start with letter,
372 # except for downstream extensions which must start with __RFQDN_.
373 # Dots are only valid in the downstream extension prefix.
374 valid_name = re.compile('^(__[a-zA-Z0-9.-]+_)?'
375                         '[a-zA-Z][a-zA-Z0-9_-]*$')
376
377
378 def check_name(expr_info, source, name, allow_optional=False,
379                enum_member=False):
380     global valid_name
381     membername = name
382
383     if not isinstance(name, str):
384         raise QAPIExprError(expr_info,
385                             "%s requires a string name" % source)
386     if name.startswith('*'):
387         membername = name[1:]
388         if not allow_optional:
389             raise QAPIExprError(expr_info,
390                                 "%s does not allow optional name '%s'"
391                                 % (source, name))
392     # Enum members can start with a digit, because the generated C
393     # code always prefixes it with the enum name
394     if enum_member and membername[0].isdigit():
395         membername = 'D' + membername
396     # Reserve the entire 'q_' namespace for c_name(), and for 'q_empty'
397     # and 'q_obj_*' implicit type names.
398     if not valid_name.match(membername) or \
399        c_name(membername, False).startswith('q_'):
400         raise QAPIExprError(expr_info,
401                             "%s uses invalid name '%s'" % (source, name))
402
403
404 def add_name(name, info, meta, implicit=False):
405     global all_names
406     check_name(info, "'%s'" % meta, name)
407     # FIXME should reject names that differ only in '_' vs. '.'
408     # vs. '-', because they're liable to clash in generated C.
409     if name in all_names:
410         raise QAPIExprError(info,
411                             "%s '%s' is already defined"
412                             % (all_names[name], name))
413     if not implicit and (name.endswith('Kind') or name.endswith('List')):
414         raise QAPIExprError(info,
415                             "%s '%s' should not end in '%s'"
416                             % (meta, name, name[-4:]))
417     all_names[name] = meta
418
419
420 def add_struct(definition, info):
421     global struct_types
422     name = definition['struct']
423     add_name(name, info, 'struct')
424     struct_types.append(definition)
425
426
427 def find_struct(name):
428     global struct_types
429     for struct in struct_types:
430         if struct['struct'] == name:
431             return struct
432     return None
433
434
435 def add_union(definition, info):
436     global union_types
437     name = definition['union']
438     add_name(name, info, 'union')
439     union_types.append(definition)
440
441
442 def find_union(name):
443     global union_types
444     for union in union_types:
445         if union['union'] == name:
446             return union
447     return None
448
449
450 def add_enum(name, info, enum_values=None, implicit=False):
451     global enum_types
452     add_name(name, info, 'enum', implicit)
453     enum_types.append({"enum_name": name, "enum_values": enum_values})
454
455
456 def find_enum(name):
457     global enum_types
458     for enum in enum_types:
459         if enum['enum_name'] == name:
460             return enum
461     return None
462
463
464 def is_enum(name):
465     return find_enum(name) is not None
466
467
468 def check_type(expr_info, source, value, allow_array=False,
469                allow_dict=False, allow_optional=False,
470                allow_metas=[]):
471     global all_names
472
473     if value is None:
474         return
475
476     # Check if array type for value is okay
477     if isinstance(value, list):
478         if not allow_array:
479             raise QAPIExprError(expr_info,
480                                 "%s cannot be an array" % source)
481         if len(value) != 1 or not isinstance(value[0], str):
482             raise QAPIExprError(expr_info,
483                                 "%s: array type must contain single type name"
484                                 % source)
485         value = value[0]
486
487     # Check if type name for value is okay
488     if isinstance(value, str):
489         if value not in all_names:
490             raise QAPIExprError(expr_info,
491                                 "%s uses unknown type '%s'"
492                                 % (source, value))
493         if not all_names[value] in allow_metas:
494             raise QAPIExprError(expr_info,
495                                 "%s cannot use %s type '%s'"
496                                 % (source, all_names[value], value))
497         return
498
499     if not allow_dict:
500         raise QAPIExprError(expr_info,
501                             "%s should be a type name" % source)
502
503     if not isinstance(value, OrderedDict):
504         raise QAPIExprError(expr_info,
505                             "%s should be a dictionary or type name" % source)
506
507     # value is a dictionary, check that each member is okay
508     for (key, arg) in value.items():
509         check_name(expr_info, "Member of %s" % source, key,
510                    allow_optional=allow_optional)
511         if c_name(key, False) == 'u' or c_name(key, False).startswith('has_'):
512             raise QAPIExprError(expr_info,
513                                 "Member of %s uses reserved name '%s'"
514                                 % (source, key))
515         # Todo: allow dictionaries to represent default values of
516         # an optional argument.
517         check_type(expr_info, "Member '%s' of %s" % (key, source), arg,
518                    allow_array=True,
519                    allow_metas=['built-in', 'union', 'alternate', 'struct',
520                                 'enum'])
521
522
523 def check_command(expr, expr_info):
524     name = expr['command']
525
526     check_type(expr_info, "'data' for command '%s'" % name,
527                expr.get('data'), allow_dict=True, allow_optional=True,
528                allow_metas=['struct'])
529     returns_meta = ['union', 'struct']
530     if name in returns_whitelist:
531         returns_meta += ['built-in', 'alternate', 'enum']
532     check_type(expr_info, "'returns' for command '%s'" % name,
533                expr.get('returns'), allow_array=True,
534                allow_optional=True, allow_metas=returns_meta)
535
536
537 def check_event(expr, expr_info):
538     global events
539     name = expr['event']
540
541     events.append(name)
542     check_type(expr_info, "'data' for event '%s'" % name,
543                expr.get('data'), allow_dict=True, allow_optional=True,
544                allow_metas=['struct'])
545
546
547 def check_union(expr, expr_info):
548     name = expr['union']
549     base = expr.get('base')
550     discriminator = expr.get('discriminator')
551     members = expr['data']
552
553     # Two types of unions, determined by discriminator.
554
555     # With no discriminator it is a simple union.
556     if discriminator is None:
557         enum_define = None
558         allow_metas = ['built-in', 'union', 'alternate', 'struct', 'enum']
559         if base is not None:
560             raise QAPIExprError(expr_info,
561                                 "Simple union '%s' must not have a base"
562                                 % name)
563
564     # Else, it's a flat union.
565     else:
566         # The object must have a string or dictionary 'base'.
567         check_type(expr_info, "'base' for union '%s'" % name,
568                    base, allow_dict=True, allow_optional=True,
569                    allow_metas=['struct'])
570         if not base:
571             raise QAPIExprError(expr_info,
572                                 "Flat union '%s' must have a base"
573                                 % name)
574         base_members = find_base_members(base)
575         assert base_members
576
577         # The value of member 'discriminator' must name a non-optional
578         # member of the base struct.
579         check_name(expr_info, "Discriminator of flat union '%s'" % name,
580                    discriminator)
581         discriminator_type = base_members.get(discriminator)
582         if not discriminator_type:
583             raise QAPIExprError(expr_info,
584                                 "Discriminator '%s' is not a member of base "
585                                 "struct '%s'"
586                                 % (discriminator, base))
587         enum_define = find_enum(discriminator_type)
588         allow_metas = ['struct']
589         # Do not allow string discriminator
590         if not enum_define:
591             raise QAPIExprError(expr_info,
592                                 "Discriminator '%s' must be of enumeration "
593                                 "type" % discriminator)
594
595     # Check every branch; don't allow an empty union
596     if len(members) == 0:
597         raise QAPIExprError(expr_info,
598                             "Union '%s' cannot have empty 'data'" % name)
599     for (key, value) in members.items():
600         check_name(expr_info, "Member of union '%s'" % name, key)
601
602         # Each value must name a known type
603         check_type(expr_info, "Member '%s' of union '%s'" % (key, name),
604                    value, allow_array=not base, allow_metas=allow_metas)
605
606         # If the discriminator names an enum type, then all members
607         # of 'data' must also be members of the enum type.
608         if enum_define:
609             if key not in enum_define['enum_values']:
610                 raise QAPIExprError(expr_info,
611                                     "Discriminator value '%s' is not found in "
612                                     "enum '%s'" %
613                                     (key, enum_define["enum_name"]))
614
615
616 def check_alternate(expr, expr_info):
617     name = expr['alternate']
618     members = expr['data']
619     types_seen = {}
620
621     # Check every branch; require at least two branches
622     if len(members) < 2:
623         raise QAPIExprError(expr_info,
624                             "Alternate '%s' should have at least two branches "
625                             "in 'data'" % name)
626     for (key, value) in members.items():
627         check_name(expr_info, "Member of alternate '%s'" % name, key)
628
629         # Ensure alternates have no type conflicts.
630         check_type(expr_info, "Member '%s' of alternate '%s'" % (key, name),
631                    value,
632                    allow_metas=['built-in', 'union', 'struct', 'enum'])
633         qtype = find_alternate_member_qtype(value)
634         if not qtype:
635             raise QAPIExprError(expr_info,
636                                 "Alternate '%s' member '%s' cannot use "
637                                 "type '%s'" % (name, key, value))
638         if qtype in types_seen:
639             raise QAPIExprError(expr_info,
640                                 "Alternate '%s' member '%s' can't "
641                                 "be distinguished from member '%s'"
642                                 % (name, key, types_seen[qtype]))
643         types_seen[qtype] = key
644
645
646 def check_enum(expr, expr_info):
647     name = expr['enum']
648     members = expr.get('data')
649     prefix = expr.get('prefix')
650
651     if not isinstance(members, list):
652         raise QAPIExprError(expr_info,
653                             "Enum '%s' requires an array for 'data'" % name)
654     if prefix is not None and not isinstance(prefix, str):
655         raise QAPIExprError(expr_info,
656                             "Enum '%s' requires a string for 'prefix'" % name)
657     for member in members:
658         check_name(expr_info, "Member of enum '%s'" % name, member,
659                    enum_member=True)
660
661
662 def check_struct(expr, expr_info):
663     name = expr['struct']
664     members = expr['data']
665
666     check_type(expr_info, "'data' for struct '%s'" % name, members,
667                allow_dict=True, allow_optional=True)
668     check_type(expr_info, "'base' for struct '%s'" % name, expr.get('base'),
669                allow_metas=['struct'])
670
671
672 def check_keys(expr_elem, meta, required, optional=[]):
673     expr = expr_elem['expr']
674     info = expr_elem['info']
675     name = expr[meta]
676     if not isinstance(name, str):
677         raise QAPIExprError(info,
678                             "'%s' key must have a string value" % meta)
679     required = required + [meta]
680     for (key, value) in expr.items():
681         if key not in required and key not in optional:
682             raise QAPIExprError(info,
683                                 "Unknown key '%s' in %s '%s'"
684                                 % (key, meta, name))
685         if (key == 'gen' or key == 'success-response') and value is not False:
686             raise QAPIExprError(info,
687                                 "'%s' of %s '%s' should only use false value"
688                                 % (key, meta, name))
689     for key in required:
690         if key not in expr:
691             raise QAPIExprError(info,
692                                 "Key '%s' is missing from %s '%s'"
693                                 % (key, meta, name))
694
695
696 def check_exprs(exprs):
697     global all_names
698
699     # Learn the types and check for valid expression keys
700     for builtin in builtin_types.keys():
701         all_names[builtin] = 'built-in'
702     for expr_elem in exprs:
703         expr = expr_elem['expr']
704         info = expr_elem['info']
705         if 'enum' in expr:
706             check_keys(expr_elem, 'enum', ['data'], ['prefix'])
707             add_enum(expr['enum'], info, expr['data'])
708         elif 'union' in expr:
709             check_keys(expr_elem, 'union', ['data'],
710                        ['base', 'discriminator'])
711             add_union(expr, info)
712         elif 'alternate' in expr:
713             check_keys(expr_elem, 'alternate', ['data'])
714             add_name(expr['alternate'], info, 'alternate')
715         elif 'struct' in expr:
716             check_keys(expr_elem, 'struct', ['data'], ['base'])
717             add_struct(expr, info)
718         elif 'command' in expr:
719             check_keys(expr_elem, 'command', [],
720                        ['data', 'returns', 'gen', 'success-response'])
721             add_name(expr['command'], info, 'command')
722         elif 'event' in expr:
723             check_keys(expr_elem, 'event', [], ['data'])
724             add_name(expr['event'], info, 'event')
725         else:
726             raise QAPIExprError(expr_elem['info'],
727                                 "Expression is missing metatype")
728
729     # Try again for hidden UnionKind enum
730     for expr_elem in exprs:
731         expr = expr_elem['expr']
732         if 'union' in expr:
733             if not discriminator_find_enum_define(expr):
734                 add_enum('%sKind' % expr['union'], expr_elem['info'],
735                          implicit=True)
736         elif 'alternate' in expr:
737             add_enum('%sKind' % expr['alternate'], expr_elem['info'],
738                      implicit=True)
739
740     # Validate that exprs make sense
741     for expr_elem in exprs:
742         expr = expr_elem['expr']
743         info = expr_elem['info']
744
745         if 'enum' in expr:
746             check_enum(expr, info)
747         elif 'union' in expr:
748             check_union(expr, info)
749         elif 'alternate' in expr:
750             check_alternate(expr, info)
751         elif 'struct' in expr:
752             check_struct(expr, info)
753         elif 'command' in expr:
754             check_command(expr, info)
755         elif 'event' in expr:
756             check_event(expr, info)
757         else:
758             assert False, 'unexpected meta type'
759
760     return exprs
761
762
763 #
764 # Schema compiler frontend
765 #
766
767 class QAPISchemaEntity(object):
768     def __init__(self, name, info):
769         assert isinstance(name, str)
770         self.name = name
771         # For explicitly defined entities, info points to the (explicit)
772         # definition.  For builtins (and their arrays), info is None.
773         # For implicitly defined entities, info points to a place that
774         # triggered the implicit definition (there may be more than one
775         # such place).
776         self.info = info
777
778     def c_name(self):
779         return c_name(self.name)
780
781     def check(self, schema):
782         pass
783
784     def is_implicit(self):
785         return not self.info
786
787     def visit(self, visitor):
788         pass
789
790
791 class QAPISchemaVisitor(object):
792     def visit_begin(self, schema):
793         pass
794
795     def visit_end(self):
796         pass
797
798     def visit_needed(self, entity):
799         # Default to visiting everything
800         return True
801
802     def visit_builtin_type(self, name, info, json_type):
803         pass
804
805     def visit_enum_type(self, name, info, values, prefix):
806         pass
807
808     def visit_array_type(self, name, info, element_type):
809         pass
810
811     def visit_object_type(self, name, info, base, members, variants):
812         pass
813
814     def visit_object_type_flat(self, name, info, members, variants):
815         pass
816
817     def visit_alternate_type(self, name, info, variants):
818         pass
819
820     def visit_command(self, name, info, arg_type, ret_type,
821                       gen, success_response):
822         pass
823
824     def visit_event(self, name, info, arg_type):
825         pass
826
827
828 class QAPISchemaType(QAPISchemaEntity):
829     # Return the C type for common use.
830     # For the types we commonly box, this is a pointer type.
831     def c_type(self):
832         pass
833
834     # Return the C type to be used in a parameter list.
835     def c_param_type(self):
836         return self.c_type()
837
838     # Return the C type to be used where we suppress boxing.
839     def c_unboxed_type(self):
840         return self.c_type()
841
842     def json_type(self):
843         pass
844
845     def alternate_qtype(self):
846         json2qtype = {
847             'string':  'QTYPE_QSTRING',
848             'number':  'QTYPE_QFLOAT',
849             'int':     'QTYPE_QINT',
850             'boolean': 'QTYPE_QBOOL',
851             'object':  'QTYPE_QDICT'
852         }
853         return json2qtype.get(self.json_type())
854
855
856 class QAPISchemaBuiltinType(QAPISchemaType):
857     def __init__(self, name, json_type, c_type):
858         QAPISchemaType.__init__(self, name, None)
859         assert not c_type or isinstance(c_type, str)
860         assert json_type in ('string', 'number', 'int', 'boolean', 'null',
861                              'value')
862         self._json_type_name = json_type
863         self._c_type_name = c_type
864
865     def c_name(self):
866         return self.name
867
868     def c_type(self):
869         return self._c_type_name
870
871     def c_param_type(self):
872         if self.name == 'str':
873             return 'const ' + self._c_type_name
874         return self._c_type_name
875
876     def json_type(self):
877         return self._json_type_name
878
879     def visit(self, visitor):
880         visitor.visit_builtin_type(self.name, self.info, self.json_type())
881
882
883 class QAPISchemaEnumType(QAPISchemaType):
884     def __init__(self, name, info, values, prefix):
885         QAPISchemaType.__init__(self, name, info)
886         for v in values:
887             assert isinstance(v, QAPISchemaMember)
888             v.set_owner(name)
889         assert prefix is None or isinstance(prefix, str)
890         self.values = values
891         self.prefix = prefix
892
893     def check(self, schema):
894         seen = {}
895         for v in self.values:
896             v.check_clash(self.info, seen)
897
898     def is_implicit(self):
899         # See QAPISchema._make_implicit_enum_type()
900         return self.name.endswith('Kind')
901
902     def c_type(self):
903         return c_name(self.name)
904
905     def member_names(self):
906         return [v.name for v in self.values]
907
908     def json_type(self):
909         return 'string'
910
911     def visit(self, visitor):
912         visitor.visit_enum_type(self.name, self.info,
913                                 self.member_names(), self.prefix)
914
915
916 class QAPISchemaArrayType(QAPISchemaType):
917     def __init__(self, name, info, element_type):
918         QAPISchemaType.__init__(self, name, info)
919         assert isinstance(element_type, str)
920         self._element_type_name = element_type
921         self.element_type = None
922
923     def check(self, schema):
924         self.element_type = schema.lookup_type(self._element_type_name)
925         assert self.element_type
926
927     def is_implicit(self):
928         return True
929
930     def c_type(self):
931         return c_name(self.name) + pointer_suffix
932
933     def json_type(self):
934         return 'array'
935
936     def visit(self, visitor):
937         visitor.visit_array_type(self.name, self.info, self.element_type)
938
939
940 class QAPISchemaObjectType(QAPISchemaType):
941     def __init__(self, name, info, base, local_members, variants):
942         # struct has local_members, optional base, and no variants
943         # flat union has base, variants, and no local_members
944         # simple union has local_members, variants, and no base
945         QAPISchemaType.__init__(self, name, info)
946         assert base is None or isinstance(base, str)
947         for m in local_members:
948             assert isinstance(m, QAPISchemaObjectTypeMember)
949             m.set_owner(name)
950         if variants is not None:
951             assert isinstance(variants, QAPISchemaObjectTypeVariants)
952             variants.set_owner(name)
953         self._base_name = base
954         self.base = None
955         self.local_members = local_members
956         self.variants = variants
957         self.members = None
958
959     def check(self, schema):
960         if self.members is False:               # check for cycles
961             raise QAPIExprError(self.info,
962                                 "Object %s contains itself" % self.name)
963         if self.members:
964             return
965         self.members = False                    # mark as being checked
966         seen = OrderedDict()
967         if self._base_name:
968             self.base = schema.lookup_type(self._base_name)
969             assert isinstance(self.base, QAPISchemaObjectType)
970             self.base.check(schema)
971             self.base.check_clash(schema, self.info, seen)
972         for m in self.local_members:
973             m.check(schema)
974             m.check_clash(self.info, seen)
975         self.members = seen.values()
976         if self.variants:
977             self.variants.check(schema, seen)
978             assert self.variants.tag_member in self.members
979             self.variants.check_clash(schema, self.info, seen)
980
981     # Check that the members of this type do not cause duplicate JSON members,
982     # and update seen to track the members seen so far. Report any errors
983     # on behalf of info, which is not necessarily self.info
984     def check_clash(self, schema, info, seen):
985         assert not self.variants       # not implemented
986         for m in self.members:
987             m.check_clash(info, seen)
988
989     def is_implicit(self):
990         # See QAPISchema._make_implicit_object_type(), as well as
991         # _def_predefineds()
992         return self.name.startswith('q_')
993
994     def c_name(self):
995         return QAPISchemaType.c_name(self)
996
997     def c_type(self):
998         assert not self.is_implicit()
999         return c_name(self.name) + pointer_suffix
1000
1001     def c_unboxed_type(self):
1002         return c_name(self.name)
1003
1004     def json_type(self):
1005         return 'object'
1006
1007     def visit(self, visitor):
1008         visitor.visit_object_type(self.name, self.info,
1009                                   self.base, self.local_members, self.variants)
1010         visitor.visit_object_type_flat(self.name, self.info,
1011                                        self.members, self.variants)
1012
1013
1014 class QAPISchemaMember(object):
1015     role = 'member'
1016
1017     def __init__(self, name):
1018         assert isinstance(name, str)
1019         self.name = name
1020         self.owner = None
1021
1022     def set_owner(self, name):
1023         assert not self.owner
1024         self.owner = name
1025
1026     def check_clash(self, info, seen):
1027         cname = c_name(self.name)
1028         if cname.lower() != cname and self.owner not in case_whitelist:
1029             raise QAPIExprError(info,
1030                                 "%s should not use uppercase" % self.describe())
1031         if cname in seen:
1032             raise QAPIExprError(info,
1033                                 "%s collides with %s"
1034                                 % (self.describe(), seen[cname].describe()))
1035         seen[cname] = self
1036
1037     def _pretty_owner(self):
1038         owner = self.owner
1039         if owner.startswith('q_obj_'):
1040             # See QAPISchema._make_implicit_object_type() - reverse the
1041             # mapping there to create a nice human-readable description
1042             owner = owner[6:]
1043             if owner.endswith('-arg'):
1044                 return '(parameter of %s)' % owner[:-4]
1045             elif owner.endswith('-base'):
1046                 return '(base of %s)' % owner[:-5]
1047             else:
1048                 assert owner.endswith('-wrapper')
1049                 # Unreachable and not implemented
1050                 assert False
1051         if owner.endswith('Kind'):
1052             # See QAPISchema._make_implicit_enum_type()
1053             return '(branch of %s)' % owner[:-4]
1054         return '(%s of %s)' % (self.role, owner)
1055
1056     def describe(self):
1057         return "'%s' %s" % (self.name, self._pretty_owner())
1058
1059
1060 class QAPISchemaObjectTypeMember(QAPISchemaMember):
1061     def __init__(self, name, typ, optional):
1062         QAPISchemaMember.__init__(self, name)
1063         assert isinstance(typ, str)
1064         assert isinstance(optional, bool)
1065         self._type_name = typ
1066         self.type = None
1067         self.optional = optional
1068
1069     def check(self, schema):
1070         assert self.owner
1071         self.type = schema.lookup_type(self._type_name)
1072         assert self.type
1073
1074
1075 class QAPISchemaObjectTypeVariants(object):
1076     def __init__(self, tag_name, tag_member, variants):
1077         # Flat unions pass tag_name but not tag_member.
1078         # Simple unions and alternates pass tag_member but not tag_name.
1079         # After check(), tag_member is always set, and tag_name remains
1080         # a reliable witness of being used by a flat union.
1081         assert bool(tag_member) != bool(tag_name)
1082         assert (isinstance(tag_name, str) or
1083                 isinstance(tag_member, QAPISchemaObjectTypeMember))
1084         assert len(variants) > 0
1085         for v in variants:
1086             assert isinstance(v, QAPISchemaObjectTypeVariant)
1087         self.tag_name = tag_name
1088         self.tag_member = tag_member
1089         self.variants = variants
1090
1091     def set_owner(self, name):
1092         for v in self.variants:
1093             v.set_owner(name)
1094
1095     def check(self, schema, seen):
1096         if not self.tag_member:    # flat union
1097             self.tag_member = seen[c_name(self.tag_name)]
1098             assert self.tag_name == self.tag_member.name
1099         assert isinstance(self.tag_member.type, QAPISchemaEnumType)
1100         for v in self.variants:
1101             v.check(schema)
1102             # Union names must match enum values; alternate names are
1103             # checked separately. Use 'seen' to tell the two apart.
1104             if seen:
1105                 assert v.name in self.tag_member.type.member_names()
1106                 assert isinstance(v.type, QAPISchemaObjectType)
1107                 v.type.check(schema)
1108
1109     def check_clash(self, schema, info, seen):
1110         for v in self.variants:
1111             # Reset seen map for each variant, since qapi names from one
1112             # branch do not affect another branch
1113             assert isinstance(v.type, QAPISchemaObjectType)
1114             v.type.check_clash(schema, info, dict(seen))
1115
1116
1117 class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
1118     role = 'branch'
1119
1120     def __init__(self, name, typ):
1121         QAPISchemaObjectTypeMember.__init__(self, name, typ, False)
1122
1123
1124 class QAPISchemaAlternateType(QAPISchemaType):
1125     def __init__(self, name, info, variants):
1126         QAPISchemaType.__init__(self, name, info)
1127         assert isinstance(variants, QAPISchemaObjectTypeVariants)
1128         assert not variants.tag_name
1129         variants.set_owner(name)
1130         variants.tag_member.set_owner(self.name)
1131         self.variants = variants
1132
1133     def check(self, schema):
1134         self.variants.tag_member.check(schema)
1135         # Not calling self.variants.check_clash(), because there's nothing
1136         # to clash with
1137         self.variants.check(schema, {})
1138         # Alternate branch names have no relation to the tag enum values;
1139         # so we have to check for potential name collisions ourselves.
1140         seen = {}
1141         for v in self.variants.variants:
1142             v.check_clash(self.info, seen)
1143
1144     def c_type(self):
1145         return c_name(self.name) + pointer_suffix
1146
1147     def json_type(self):
1148         return 'value'
1149
1150     def visit(self, visitor):
1151         visitor.visit_alternate_type(self.name, self.info, self.variants)
1152
1153
1154 class QAPISchemaCommand(QAPISchemaEntity):
1155     def __init__(self, name, info, arg_type, ret_type, gen, success_response):
1156         QAPISchemaEntity.__init__(self, name, info)
1157         assert not arg_type or isinstance(arg_type, str)
1158         assert not ret_type or isinstance(ret_type, str)
1159         self._arg_type_name = arg_type
1160         self.arg_type = None
1161         self._ret_type_name = ret_type
1162         self.ret_type = None
1163         self.gen = gen
1164         self.success_response = success_response
1165
1166     def check(self, schema):
1167         if self._arg_type_name:
1168             self.arg_type = schema.lookup_type(self._arg_type_name)
1169             assert isinstance(self.arg_type, QAPISchemaObjectType)
1170             assert not self.arg_type.variants   # not implemented
1171         if self._ret_type_name:
1172             self.ret_type = schema.lookup_type(self._ret_type_name)
1173             assert isinstance(self.ret_type, QAPISchemaType)
1174
1175     def visit(self, visitor):
1176         visitor.visit_command(self.name, self.info,
1177                               self.arg_type, self.ret_type,
1178                               self.gen, self.success_response)
1179
1180
1181 class QAPISchemaEvent(QAPISchemaEntity):
1182     def __init__(self, name, info, arg_type):
1183         QAPISchemaEntity.__init__(self, name, info)
1184         assert not arg_type or isinstance(arg_type, str)
1185         self._arg_type_name = arg_type
1186         self.arg_type = None
1187
1188     def check(self, schema):
1189         if self._arg_type_name:
1190             self.arg_type = schema.lookup_type(self._arg_type_name)
1191             assert isinstance(self.arg_type, QAPISchemaObjectType)
1192             assert not self.arg_type.variants   # not implemented
1193
1194     def visit(self, visitor):
1195         visitor.visit_event(self.name, self.info, self.arg_type)
1196
1197
1198 class QAPISchema(object):
1199     def __init__(self, fname):
1200         try:
1201             self.exprs = check_exprs(QAPISchemaParser(open(fname, "r")).exprs)
1202             self._entity_dict = {}
1203             self._predefining = True
1204             self._def_predefineds()
1205             self._predefining = False
1206             self._def_exprs()
1207             self.check()
1208         except (QAPISchemaError, QAPIExprError) as err:
1209             print >>sys.stderr, err
1210             exit(1)
1211
1212     def _def_entity(self, ent):
1213         # Only the predefined types are allowed to not have info
1214         assert ent.info or self._predefining
1215         assert ent.name not in self._entity_dict
1216         self._entity_dict[ent.name] = ent
1217
1218     def lookup_entity(self, name, typ=None):
1219         ent = self._entity_dict.get(name)
1220         if typ and not isinstance(ent, typ):
1221             return None
1222         return ent
1223
1224     def lookup_type(self, name):
1225         return self.lookup_entity(name, QAPISchemaType)
1226
1227     def _def_builtin_type(self, name, json_type, c_type):
1228         self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type))
1229         # TODO As long as we have QAPI_TYPES_BUILTIN to share multiple
1230         # qapi-types.h from a single .c, all arrays of builtins must be
1231         # declared in the first file whether or not they are used.  Nicer
1232         # would be to use lazy instantiation, while figuring out how to
1233         # avoid compilation issues with multiple qapi-types.h.
1234         self._make_array_type(name, None)
1235
1236     def _def_predefineds(self):
1237         for t in [('str',    'string',  'char' + pointer_suffix),
1238                   ('number', 'number',  'double'),
1239                   ('int',    'int',     'int64_t'),
1240                   ('int8',   'int',     'int8_t'),
1241                   ('int16',  'int',     'int16_t'),
1242                   ('int32',  'int',     'int32_t'),
1243                   ('int64',  'int',     'int64_t'),
1244                   ('uint8',  'int',     'uint8_t'),
1245                   ('uint16', 'int',     'uint16_t'),
1246                   ('uint32', 'int',     'uint32_t'),
1247                   ('uint64', 'int',     'uint64_t'),
1248                   ('size',   'int',     'uint64_t'),
1249                   ('bool',   'boolean', 'bool'),
1250                   ('any',    'value',   'QObject' + pointer_suffix)]:
1251             self._def_builtin_type(*t)
1252         self.the_empty_object_type = QAPISchemaObjectType('q_empty', None,
1253                                                           None, [], None)
1254         self._def_entity(self.the_empty_object_type)
1255         qtype_values = self._make_enum_members(['none', 'qnull', 'qint',
1256                                                 'qstring', 'qdict', 'qlist',
1257                                                 'qfloat', 'qbool'])
1258         self._def_entity(QAPISchemaEnumType('QType', None, qtype_values,
1259                                             'QTYPE'))
1260
1261     def _make_enum_members(self, values):
1262         return [QAPISchemaMember(v) for v in values]
1263
1264     def _make_implicit_enum_type(self, name, info, values):
1265         # See also QAPISchemaObjectTypeMember._pretty_owner()
1266         name = name + 'Kind'   # Use namespace reserved by add_name()
1267         self._def_entity(QAPISchemaEnumType(
1268             name, info, self._make_enum_members(values), None))
1269         return name
1270
1271     def _make_array_type(self, element_type, info):
1272         name = element_type + 'List'   # Use namespace reserved by add_name()
1273         if not self.lookup_type(name):
1274             self._def_entity(QAPISchemaArrayType(name, info, element_type))
1275         return name
1276
1277     def _make_implicit_object_type(self, name, info, role, members):
1278         if not members:
1279             return None
1280         # See also QAPISchemaObjectTypeMember._pretty_owner()
1281         name = 'q_obj_%s-%s' % (name, role)
1282         if not self.lookup_entity(name, QAPISchemaObjectType):
1283             self._def_entity(QAPISchemaObjectType(name, info, None,
1284                                                   members, None))
1285         return name
1286
1287     def _def_enum_type(self, expr, info):
1288         name = expr['enum']
1289         data = expr['data']
1290         prefix = expr.get('prefix')
1291         self._def_entity(QAPISchemaEnumType(
1292             name, info, self._make_enum_members(data), prefix))
1293
1294     def _make_member(self, name, typ, info):
1295         optional = False
1296         if name.startswith('*'):
1297             name = name[1:]
1298             optional = True
1299         if isinstance(typ, list):
1300             assert len(typ) == 1
1301             typ = self._make_array_type(typ[0], info)
1302         return QAPISchemaObjectTypeMember(name, typ, optional)
1303
1304     def _make_members(self, data, info):
1305         return [self._make_member(key, value, info)
1306                 for (key, value) in data.iteritems()]
1307
1308     def _def_struct_type(self, expr, info):
1309         name = expr['struct']
1310         base = expr.get('base')
1311         data = expr['data']
1312         self._def_entity(QAPISchemaObjectType(name, info, base,
1313                                               self._make_members(data, info),
1314                                               None))
1315
1316     def _make_variant(self, case, typ):
1317         return QAPISchemaObjectTypeVariant(case, typ)
1318
1319     def _make_simple_variant(self, case, typ, info):
1320         if isinstance(typ, list):
1321             assert len(typ) == 1
1322             typ = self._make_array_type(typ[0], info)
1323         typ = self._make_implicit_object_type(
1324             typ, info, 'wrapper', [self._make_member('data', typ, info)])
1325         return QAPISchemaObjectTypeVariant(case, typ)
1326
1327     def _def_union_type(self, expr, info):
1328         name = expr['union']
1329         data = expr['data']
1330         base = expr.get('base')
1331         tag_name = expr.get('discriminator')
1332         tag_member = None
1333         if isinstance(base, dict):
1334             base = (self._make_implicit_object_type(
1335                     name, info, 'base', self._make_members(base, info)))
1336         if tag_name:
1337             variants = [self._make_variant(key, value)
1338                         for (key, value) in data.iteritems()]
1339             members = []
1340         else:
1341             variants = [self._make_simple_variant(key, value, info)
1342                         for (key, value) in data.iteritems()]
1343             typ = self._make_implicit_enum_type(name, info,
1344                                                 [v.name for v in variants])
1345             tag_member = QAPISchemaObjectTypeMember('type', typ, False)
1346             members = [tag_member]
1347         self._def_entity(
1348             QAPISchemaObjectType(name, info, base, members,
1349                                  QAPISchemaObjectTypeVariants(tag_name,
1350                                                               tag_member,
1351                                                               variants)))
1352
1353     def _def_alternate_type(self, expr, info):
1354         name = expr['alternate']
1355         data = expr['data']
1356         variants = [self._make_variant(key, value)
1357                     for (key, value) in data.iteritems()]
1358         tag_member = QAPISchemaObjectTypeMember('type', 'QType', False)
1359         self._def_entity(
1360             QAPISchemaAlternateType(name, info,
1361                                     QAPISchemaObjectTypeVariants(None,
1362                                                                  tag_member,
1363                                                                  variants)))
1364
1365     def _def_command(self, expr, info):
1366         name = expr['command']
1367         data = expr.get('data')
1368         rets = expr.get('returns')
1369         gen = expr.get('gen', True)
1370         success_response = expr.get('success-response', True)
1371         if isinstance(data, OrderedDict):
1372             data = self._make_implicit_object_type(
1373                 name, info, 'arg', self._make_members(data, info))
1374         if isinstance(rets, list):
1375             assert len(rets) == 1
1376             rets = self._make_array_type(rets[0], info)
1377         self._def_entity(QAPISchemaCommand(name, info, data, rets, gen,
1378                                            success_response))
1379
1380     def _def_event(self, expr, info):
1381         name = expr['event']
1382         data = expr.get('data')
1383         if isinstance(data, OrderedDict):
1384             data = self._make_implicit_object_type(
1385                 name, info, 'arg', self._make_members(data, info))
1386         self._def_entity(QAPISchemaEvent(name, info, data))
1387
1388     def _def_exprs(self):
1389         for expr_elem in self.exprs:
1390             expr = expr_elem['expr']
1391             info = expr_elem['info']
1392             if 'enum' in expr:
1393                 self._def_enum_type(expr, info)
1394             elif 'struct' in expr:
1395                 self._def_struct_type(expr, info)
1396             elif 'union' in expr:
1397                 self._def_union_type(expr, info)
1398             elif 'alternate' in expr:
1399                 self._def_alternate_type(expr, info)
1400             elif 'command' in expr:
1401                 self._def_command(expr, info)
1402             elif 'event' in expr:
1403                 self._def_event(expr, info)
1404             else:
1405                 assert False
1406
1407     def check(self):
1408         for ent in self._entity_dict.values():
1409             ent.check(self)
1410
1411     def visit(self, visitor):
1412         visitor.visit_begin(self)
1413         for (name, entity) in sorted(self._entity_dict.items()):
1414             if visitor.visit_needed(entity):
1415                 entity.visit(visitor)
1416         visitor.visit_end()
1417
1418
1419 #
1420 # Code generation helpers
1421 #
1422
1423 def camel_case(name):
1424     new_name = ''
1425     first = True
1426     for ch in name:
1427         if ch in ['_', '-']:
1428             first = True
1429         elif first:
1430             new_name += ch.upper()
1431             first = False
1432         else:
1433             new_name += ch.lower()
1434     return new_name
1435
1436
1437 # ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1
1438 # ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2
1439 # ENUM24_Name -> ENUM24_NAME
1440 def camel_to_upper(value):
1441     c_fun_str = c_name(value, False)
1442     if value.isupper():
1443         return c_fun_str
1444
1445     new_name = ''
1446     l = len(c_fun_str)
1447     for i in range(l):
1448         c = c_fun_str[i]
1449         # When c is upper and no "_" appears before, do more checks
1450         if c.isupper() and (i > 0) and c_fun_str[i - 1] != "_":
1451             if i < l - 1 and c_fun_str[i + 1].islower():
1452                 new_name += '_'
1453             elif c_fun_str[i - 1].isdigit():
1454                 new_name += '_'
1455         new_name += c
1456     return new_name.lstrip('_').upper()
1457
1458
1459 def c_enum_const(type_name, const_name, prefix=None):
1460     if prefix is not None:
1461         type_name = prefix
1462     return camel_to_upper(type_name) + '_' + c_name(const_name, False).upper()
1463
1464 c_name_trans = string.maketrans('.-', '__')
1465
1466
1467 # Map @name to a valid C identifier.
1468 # If @protect, avoid returning certain ticklish identifiers (like
1469 # C keywords) by prepending "q_".
1470 #
1471 # Used for converting 'name' from a 'name':'type' qapi definition
1472 # into a generated struct member, as well as converting type names
1473 # into substrings of a generated C function name.
1474 # '__a.b_c' -> '__a_b_c', 'x-foo' -> 'x_foo'
1475 # protect=True: 'int' -> 'q_int'; protect=False: 'int' -> 'int'
1476 def c_name(name, protect=True):
1477     # ANSI X3J11/88-090, 3.1.1
1478     c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue',
1479                      'default', 'do', 'double', 'else', 'enum', 'extern',
1480                      'float', 'for', 'goto', 'if', 'int', 'long', 'register',
1481                      'return', 'short', 'signed', 'sizeof', 'static',
1482                      'struct', 'switch', 'typedef', 'union', 'unsigned',
1483                      'void', 'volatile', 'while'])
1484     # ISO/IEC 9899:1999, 6.4.1
1485     c99_words = set(['inline', 'restrict', '_Bool', '_Complex', '_Imaginary'])
1486     # ISO/IEC 9899:2011, 6.4.1
1487     c11_words = set(['_Alignas', '_Alignof', '_Atomic', '_Generic',
1488                      '_Noreturn', '_Static_assert', '_Thread_local'])
1489     # GCC http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/C-Extensions.html
1490     # excluding _.*
1491     gcc_words = set(['asm', 'typeof'])
1492     # C++ ISO/IEC 14882:2003 2.11
1493     cpp_words = set(['bool', 'catch', 'class', 'const_cast', 'delete',
1494                      'dynamic_cast', 'explicit', 'false', 'friend', 'mutable',
1495                      'namespace', 'new', 'operator', 'private', 'protected',
1496                      'public', 'reinterpret_cast', 'static_cast', 'template',
1497                      'this', 'throw', 'true', 'try', 'typeid', 'typename',
1498                      'using', 'virtual', 'wchar_t',
1499                      # alternative representations
1500                      'and', 'and_eq', 'bitand', 'bitor', 'compl', 'not',
1501                      'not_eq', 'or', 'or_eq', 'xor', 'xor_eq'])
1502     # namespace pollution:
1503     polluted_words = set(['unix', 'errno', 'mips', 'sparc'])
1504     name = name.translate(c_name_trans)
1505     if protect and (name in c89_words | c99_words | c11_words | gcc_words
1506                     | cpp_words | polluted_words):
1507         return "q_" + name
1508     return name
1509
1510 eatspace = '\033EATSPACE.'
1511 pointer_suffix = ' *' + eatspace
1512
1513
1514 def genindent(count):
1515     ret = ""
1516     for _ in range(count):
1517         ret += " "
1518     return ret
1519
1520 indent_level = 0
1521
1522
1523 def push_indent(indent_amount=4):
1524     global indent_level
1525     indent_level += indent_amount
1526
1527
1528 def pop_indent(indent_amount=4):
1529     global indent_level
1530     indent_level -= indent_amount
1531
1532
1533 # Generate @code with @kwds interpolated.
1534 # Obey indent_level, and strip eatspace.
1535 def cgen(code, **kwds):
1536     raw = code % kwds
1537     if indent_level:
1538         indent = genindent(indent_level)
1539         # re.subn() lacks flags support before Python 2.7, use re.compile()
1540         raw = re.subn(re.compile("^.", re.MULTILINE),
1541                       indent + r'\g<0>', raw)
1542         raw = raw[0]
1543     return re.sub(re.escape(eatspace) + ' *', '', raw)
1544
1545
1546 def mcgen(code, **kwds):
1547     if code[0] == '\n':
1548         code = code[1:]
1549     return cgen(code, **kwds)
1550
1551
1552 def guardname(filename):
1553     return c_name(filename, protect=False).upper()
1554
1555
1556 def guardstart(name):
1557     return mcgen('''
1558
1559 #ifndef %(name)s
1560 #define %(name)s
1561
1562 ''',
1563                  name=guardname(name))
1564
1565
1566 def guardend(name):
1567     return mcgen('''
1568
1569 #endif /* %(name)s */
1570
1571 ''',
1572                  name=guardname(name))
1573
1574
1575 def gen_enum_lookup(name, values, prefix=None):
1576     ret = mcgen('''
1577
1578 const char *const %(c_name)s_lookup[] = {
1579 ''',
1580                 c_name=c_name(name))
1581     for value in values:
1582         index = c_enum_const(name, value, prefix)
1583         ret += mcgen('''
1584     [%(index)s] = "%(value)s",
1585 ''',
1586                      index=index, value=value)
1587
1588     max_index = c_enum_const(name, '_MAX', prefix)
1589     ret += mcgen('''
1590     [%(max_index)s] = NULL,
1591 };
1592 ''',
1593                  max_index=max_index)
1594     return ret
1595
1596
1597 def gen_enum(name, values, prefix=None):
1598     # append automatically generated _MAX value
1599     enum_values = values + ['_MAX']
1600
1601     ret = mcgen('''
1602
1603 typedef enum %(c_name)s {
1604 ''',
1605                 c_name=c_name(name))
1606
1607     i = 0
1608     for value in enum_values:
1609         ret += mcgen('''
1610     %(c_enum)s = %(i)d,
1611 ''',
1612                      c_enum=c_enum_const(name, value, prefix),
1613                      i=i)
1614         i += 1
1615
1616     ret += mcgen('''
1617 } %(c_name)s;
1618 ''',
1619                  c_name=c_name(name))
1620
1621     ret += mcgen('''
1622
1623 extern const char *const %(c_name)s_lookup[];
1624 ''',
1625                  c_name=c_name(name))
1626     return ret
1627
1628
1629 def gen_params(arg_type, extra):
1630     if not arg_type:
1631         return extra
1632     assert not arg_type.variants
1633     ret = ''
1634     sep = ''
1635     for memb in arg_type.members:
1636         ret += sep
1637         sep = ', '
1638         if memb.optional:
1639             ret += 'bool has_%s, ' % c_name(memb.name)
1640         ret += '%s %s' % (memb.type.c_param_type(), c_name(memb.name))
1641     if extra:
1642         ret += sep + extra
1643     return ret
1644
1645
1646 def gen_err_check():
1647     return mcgen('''
1648     if (err) {
1649         goto out;
1650     }
1651 ''')
1652
1653
1654 #
1655 # Common command line parsing
1656 #
1657
1658
1659 def parse_command_line(extra_options="", extra_long_options=[]):
1660
1661     try:
1662         opts, args = getopt.gnu_getopt(sys.argv[1:],
1663                                        "chp:o:" + extra_options,
1664                                        ["source", "header", "prefix=",
1665                                         "output-dir="] + extra_long_options)
1666     except getopt.GetoptError as err:
1667         print >>sys.stderr, "%s: %s" % (sys.argv[0], str(err))
1668         sys.exit(1)
1669
1670     output_dir = ""
1671     prefix = ""
1672     do_c = False
1673     do_h = False
1674     extra_opts = []
1675
1676     for oa in opts:
1677         o, a = oa
1678         if o in ("-p", "--prefix"):
1679             match = re.match('([A-Za-z_.-][A-Za-z0-9_.-]*)?', a)
1680             if match.end() != len(a):
1681                 print >>sys.stderr, \
1682                     "%s: 'funny character '%s' in argument of --prefix" \
1683                     % (sys.argv[0], a[match.end()])
1684                 sys.exit(1)
1685             prefix = a
1686         elif o in ("-o", "--output-dir"):
1687             output_dir = a + "/"
1688         elif o in ("-c", "--source"):
1689             do_c = True
1690         elif o in ("-h", "--header"):
1691             do_h = True
1692         else:
1693             extra_opts.append(oa)
1694
1695     if not do_c and not do_h:
1696         do_c = True
1697         do_h = True
1698
1699     if len(args) != 1:
1700         print >>sys.stderr, "%s: need exactly one argument" % sys.argv[0]
1701         sys.exit(1)
1702     fname = args[0]
1703
1704     return (fname, output_dir, do_c, do_h, prefix, extra_opts)
1705
1706 #
1707 # Generate output files with boilerplate
1708 #
1709
1710
1711 def open_output(output_dir, do_c, do_h, prefix, c_file, h_file,
1712                 c_comment, h_comment):
1713     guard = guardname(prefix + h_file)
1714     c_file = output_dir + prefix + c_file
1715     h_file = output_dir + prefix + h_file
1716
1717     if output_dir:
1718         try:
1719             os.makedirs(output_dir)
1720         except os.error as e:
1721             if e.errno != errno.EEXIST:
1722                 raise
1723
1724     def maybe_open(really, name, opt):
1725         if really:
1726             return open(name, opt)
1727         else:
1728             import StringIO
1729             return StringIO.StringIO()
1730
1731     fdef = maybe_open(do_c, c_file, 'w')
1732     fdecl = maybe_open(do_h, h_file, 'w')
1733
1734     fdef.write(mcgen('''
1735 /* AUTOMATICALLY GENERATED, DO NOT MODIFY */
1736 %(comment)s
1737 ''',
1738                      comment=c_comment))
1739
1740     fdecl.write(mcgen('''
1741 /* AUTOMATICALLY GENERATED, DO NOT MODIFY */
1742 %(comment)s
1743 #ifndef %(guard)s
1744 #define %(guard)s
1745
1746 ''',
1747                       comment=h_comment, guard=guard))
1748
1749     return (fdef, fdecl)
1750
1751
1752 def close_output(fdef, fdecl):
1753     fdecl.write('''
1754 #endif
1755 ''')
1756     fdecl.close()
1757     fdef.close()