]> git.cworth.org Git - apitrace/blob - specs/stdapi.py
Bring some of the virtual-memory-regions
[apitrace] / specs / stdapi.py
1 ##########################################################################
2 #
3 # Copyright 2008-2010 VMware, Inc.
4 # All Rights Reserved.
5 #
6 # Permission is hereby granted, free of charge, to any person obtaining a copy
7 # of this software and associated documentation files (the "Software"), to deal
8 # in the Software without restriction, including without limitation the rights
9 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 # copies of the Software, and to permit persons to whom the Software is
11 # furnished to do so, subject to the following conditions:
12 #
13 # The above copyright notice and this permission notice shall be included in
14 # all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 # THE SOFTWARE.
23 #
24 ##########################################################################/
25
26 """C basic types"""
27
28
29 import debug
30
31
32 class Type:
33
34     __all = {}
35     __seq = 0
36
37     def __init__(self, expr, id = ''):
38         self.expr = expr
39         
40         for char in id:
41             assert char.isalnum() or char in '_ '
42
43         id = id.replace(' ', '_')
44         
45         if id in Type.__all:
46             Type.__seq += 1
47             id += str(Type.__seq)
48         
49         assert id not in Type.__all
50         Type.__all[id] = self
51
52         self.id = id
53
54     def __str__(self):
55         return self.expr
56
57     def visit(self, visitor, *args, **kwargs):
58         raise NotImplementedError
59
60
61
62 class _Void(Type):
63
64     def __init__(self):
65         Type.__init__(self, "void")
66
67     def visit(self, visitor, *args, **kwargs):
68         return visitor.visit_void(self, *args, **kwargs)
69
70 Void = _Void()
71
72
73 class Literal(Type):
74
75     def __init__(self, expr, format, base=10):
76         Type.__init__(self, expr)
77         self.format = format
78
79     def visit(self, visitor, *args, **kwargs):
80         return visitor.visit_literal(self, *args, **kwargs)
81
82
83 class Const(Type):
84
85     def __init__(self, type):
86         # While "const foo" and "foo const" are synonymous, "const foo *" and
87         # "foo * const" are not quite the same, and some compilers do enforce
88         # strict const correctness.
89         if isinstance(type, String) or type is WString:
90             # For strings we never intend to say a const pointer to chars, but
91             # rather a point to const chars.
92             expr = "const " + type.expr
93         elif type.expr.startswith("const ") or '*' in type.expr:
94             expr = type.expr + " const"
95         else:
96             # The most legible
97             expr = "const " + type.expr
98
99         Type.__init__(self, expr, 'C' + type.id)
100
101         self.type = type
102
103     def visit(self, visitor, *args, **kwargs):
104         return visitor.visit_const(self, *args, **kwargs)
105
106
107 class Pointer(Type):
108
109     def __init__(self, type):
110         Type.__init__(self, type.expr + " *", 'P' + type.id)
111         self.type = type
112
113     def visit(self, visitor, *args, **kwargs):
114         return visitor.visit_pointer(self, *args, **kwargs)
115
116
117 class Handle(Type):
118
119     def __init__(self, name, type, range=None, key=None):
120         Type.__init__(self, type.expr, 'P' + type.id)
121         self.name = name
122         self.type = type
123         self.range = range
124         self.key = key
125
126     def visit(self, visitor, *args, **kwargs):
127         return visitor.visit_handle(self, *args, **kwargs)
128
129
130 def ConstPointer(type):
131     return Pointer(Const(type))
132
133
134 class Enum(Type):
135
136     def __init__(self, name, values):
137         Type.__init__(self, name)
138         self.values = list(values)
139     
140     def visit(self, visitor, *args, **kwargs):
141         return visitor.visit_enum(self, *args, **kwargs)
142
143
144 def FakeEnum(type, values):
145     return Enum(type.expr, values)
146
147
148 class Bitmask(Type):
149
150     def __init__(self, type, values):
151         Type.__init__(self, type.expr)
152         self.type = type
153         self.values = values
154
155     def visit(self, visitor, *args, **kwargs):
156         return visitor.visit_bitmask(self, *args, **kwargs)
157
158 Flags = Bitmask
159
160
161 class Array(Type):
162
163     def __init__(self, type, length):
164         Type.__init__(self, type.expr + " *")
165         self.type = type
166         self.length = length
167
168     def visit(self, visitor, *args, **kwargs):
169         return visitor.visit_array(self, *args, **kwargs)
170
171
172 class Blob(Type):
173
174     def __init__(self, type, size):
175         Type.__init__(self, type.expr + ' *')
176         self.type = type
177         self.size = size
178
179     def visit(self, visitor, *args, **kwargs):
180         return visitor.visit_blob(self, *args, **kwargs)
181
182
183 class Struct(Type):
184
185     def __init__(self, name, members):
186         Type.__init__(self, name)
187         self.name = name
188         self.members = members
189
190     def visit(self, visitor, *args, **kwargs):
191         return visitor.visit_struct(self, *args, **kwargs)
192
193
194 class Alias(Type):
195
196     def __init__(self, expr, type):
197         Type.__init__(self, expr)
198         self.type = type
199
200     def visit(self, visitor, *args, **kwargs):
201         return visitor.visit_alias(self, *args, **kwargs)
202
203
204 def Out(type, name):
205     arg = Arg(type, name, output=True)
206     return arg
207
208
209 class Arg:
210
211     def __init__(self, type, name, output=False):
212         self.type = type
213         self.name = name
214         self.output = output
215         self.index = None
216
217     def __str__(self):
218         return '%s %s' % (self.type, self.name)
219
220
221 class Function:
222
223     # 0-3 are reserved to memcpy, malloc, free, and realloc
224     __id = 4
225
226     def __init__(self, type, name, args, call = '', fail = None, sideeffects=True):
227         self.id = Function.__id
228         Function.__id += 1
229
230         self.type = type
231         self.name = name
232
233         self.args = []
234         index = 0
235         for arg in args:
236             if not isinstance(arg, Arg):
237                 if isinstance(arg, tuple):
238                     arg_type, arg_name = arg
239                 else:
240                     arg_type = arg
241                     arg_name = "arg%u" % index
242                 arg = Arg(arg_type, arg_name)
243             arg.index = index
244             index += 1
245             self.args.append(arg)
246
247         self.call = call
248         self.fail = fail
249         self.sideeffects = sideeffects
250
251     def prototype(self, name=None):
252         if name is not None:
253             name = name.strip()
254         else:
255             name = self.name
256         s = name
257         if self.call:
258             s = self.call + ' ' + s
259         if name.startswith('*'):
260             s = '(' + s + ')'
261         s = self.type.expr + ' ' + s
262         s += "("
263         if self.args:
264             s += ", ".join(["%s %s" % (arg.type, arg.name) for arg in self.args])
265         else:
266             s += "void"
267         s += ")"
268         return s
269
270
271 def StdFunction(*args, **kwargs):
272     kwargs.setdefault('call', '__stdcall')
273     return Function(*args, **kwargs)
274
275
276 def FunctionPointer(type, name, args, **kwargs):
277     # XXX: We should probably treat function pointers (callbacks or not) in a generic fashion
278     return Opaque(name)
279
280
281 class Interface(Type):
282
283     def __init__(self, name, base=None):
284         Type.__init__(self, name)
285         self.name = name
286         self.base = base
287         self.methods = []
288
289     def visit(self, visitor, *args, **kwargs):
290         return visitor.visit_interface(self, *args, **kwargs)
291
292     def itermethods(self):
293         if self.base is not None:
294             for method in self.base.itermethods():
295                 yield method
296         for method in self.methods:
297             yield method
298         raise StopIteration
299
300
301 class Method(Function):
302
303     def __init__(self, type, name, args):
304         Function.__init__(self, type, name, args, call = '__stdcall')
305         for index in range(len(self.args)):
306             self.args[index].index = index + 1
307
308
309 class String(Type):
310
311     def __init__(self, expr = "char *", length = None):
312         Type.__init__(self, expr)
313         self.length = length
314
315     def visit(self, visitor, *args, **kwargs):
316         return visitor.visit_string(self, *args, **kwargs)
317
318 # C string (i.e., zero terminated)
319 CString = String()
320
321
322 class Opaque(Type):
323     '''Opaque pointer.'''
324
325     def __init__(self, expr):
326         Type.__init__(self, expr)
327
328     def visit(self, visitor, *args, **kwargs):
329         return visitor.visit_opaque(self, *args, **kwargs)
330
331
332 def OpaquePointer(type, *args):
333     return Opaque(type.expr + ' *')
334
335 def OpaqueArray(type, size):
336     return Opaque(type.expr + ' *')
337
338 def OpaqueBlob(type, size):
339     return Opaque(type.expr + ' *')
340
341
342 class Polymorphic(Type):
343
344     def __init__(self, default_type, switch_expr, switch_types):
345         Type.__init__(self, default_type.expr)
346         self.default_type = default_type
347         self.switch_expr = switch_expr
348         self.switch_types = switch_types
349
350     def visit(self, visitor, *args, **kwargs):
351         return visitor.visit_polymorphic(self, *args, **kwargs)
352
353     def iterswitch(self):
354         cases = [['default']]
355         types = [self.default_type]
356
357         for expr, type in self.switch_types:
358             case = 'case %s' % expr
359             try:
360                 i = types.index(type)
361             except ValueError:
362                 cases.append([case])
363                 types.append(type)
364             else:
365                 cases[i].append(case)
366
367         return zip(cases, types)
368
369
370 class Visitor:
371
372     def visit(self, type, *args, **kwargs):
373         return type.visit(self, *args, **kwargs)
374
375     def visit_void(self, void, *args, **kwargs):
376         raise NotImplementedError
377
378     def visit_literal(self, literal, *args, **kwargs):
379         raise NotImplementedError
380
381     def visit_string(self, string, *args, **kwargs):
382         raise NotImplementedError
383
384     def visit_const(self, const, *args, **kwargs):
385         raise NotImplementedError
386
387     def visit_struct(self, struct, *args, **kwargs):
388         raise NotImplementedError
389
390     def visit_array(self, array, *args, **kwargs):
391         raise NotImplementedError
392
393     def visit_blob(self, blob, *args, **kwargs):
394         raise NotImplementedError
395
396     def visit_enum(self, enum, *args, **kwargs):
397         raise NotImplementedError
398
399     def visit_bitmask(self, bitmask, *args, **kwargs):
400         raise NotImplementedError
401
402     def visit_pointer(self, pointer, *args, **kwargs):
403         raise NotImplementedError
404
405     def visit_handle(self, handle, *args, **kwargs):
406         raise NotImplementedError
407
408     def visit_alias(self, alias, *args, **kwargs):
409         raise NotImplementedError
410
411     def visit_opaque(self, opaque, *args, **kwargs):
412         raise NotImplementedError
413
414     def visit_interface(self, interface, *args, **kwargs):
415         raise NotImplementedError
416
417     def visit_polymorphic(self, polymorphic, *args, **kwargs):
418         raise NotImplementedError
419         #return self.visit(polymorphic.default_type, *args, **kwargs)
420
421
422 class OnceVisitor(Visitor):
423
424     def __init__(self):
425         self.__visited = set()
426
427     def visit(self, type, *args, **kwargs):
428         if type not in self.__visited:
429             self.__visited.add(type)
430             return type.visit(self, *args, **kwargs)
431         return None
432
433
434 class Rebuilder(Visitor):
435
436     def visit_void(self, void):
437         return void
438
439     def visit_literal(self, literal):
440         return literal
441
442     def visit_string(self, string):
443         return string
444
445     def visit_const(self, const):
446         return Const(const.type)
447
448     def visit_struct(self, struct):
449         members = [(self.visit(type), name) for type, name in struct.members]
450         return Struct(struct.name, members)
451
452     def visit_array(self, array):
453         type = self.visit(array.type)
454         return Array(type, array.length)
455
456     def visit_blob(self, blob):
457         type = self.visit(blob.type)
458         return Blob(type, blob.size)
459
460     def visit_enum(self, enum):
461         return enum
462
463     def visit_bitmask(self, bitmask):
464         type = self.visit(bitmask.type)
465         return Bitmask(type, bitmask.values)
466
467     def visit_pointer(self, pointer):
468         type = self.visit(pointer.type)
469         return Pointer(type)
470
471     def visit_handle(self, handle):
472         type = self.visit(handle.type)
473         return Handle(handle.name, type, range=handle.range, key=handle.key)
474
475     def visit_alias(self, alias):
476         type = self.visit(alias.type)
477         return Alias(alias.expr, type)
478
479     def visit_opaque(self, opaque):
480         return opaque
481
482     def visit_polymorphic(self, polymorphic):
483         default_type = self.visit(polymorphic.default_type)
484         switch_expr = polymorphic.switch_expr
485         switch_types = [(expr, self.visit(type)) for expr, type in polymorphic.switch_types]
486         return Polymorphic(default_type, switch_expr, switch_types)
487
488
489 class Collector(Visitor):
490     '''Collect.'''
491
492     def __init__(self):
493         self.__visited = set()
494         self.types = []
495
496     def visit(self, type):
497         if type in self.__visited:
498             return
499         self.__visited.add(type)
500         Visitor.visit(self, type)
501         self.types.append(type)
502
503     def visit_void(self, literal):
504         pass
505
506     def visit_literal(self, literal):
507         pass
508
509     def visit_string(self, string):
510         pass
511
512     def visit_const(self, const):
513         self.visit(const.type)
514
515     def visit_struct(self, struct):
516         for type, name in struct.members:
517             self.visit(type)
518
519     def visit_array(self, array):
520         self.visit(array.type)
521
522     def visit_blob(self, array):
523         pass
524
525     def visit_enum(self, enum):
526         pass
527
528     def visit_bitmask(self, bitmask):
529         self.visit(bitmask.type)
530
531     def visit_pointer(self, pointer):
532         self.visit(pointer.type)
533
534     def visit_handle(self, handle):
535         self.visit(handle.type)
536
537     def visit_alias(self, alias):
538         self.visit(alias.type)
539
540     def visit_opaque(self, opaque):
541         pass
542
543     def visit_interface(self, interface):
544         if interface.base is not None:
545             self.visit(interface.base)
546         for method in interface.itermethods():
547             for arg in method.args:
548                 self.visit(arg.type)
549             self.visit(method.type)
550
551     def visit_polymorphic(self, polymorphic):
552         self.visit(polymorphic.default_type)
553         for expr, type in polymorphic.switch_types:
554             self.visit(type)
555
556
557 class API:
558
559     def __init__(self, name = None):
560         self.name = name
561         self.headers = []
562         self.functions = []
563         self.interfaces = []
564
565     def all_types(self):
566         collector = Collector()
567         for function in self.functions:
568             for arg in function.args:
569                 collector.visit(arg.type)
570             collector.visit(function.type)
571         for interface in self.interfaces:
572             collector.visit(interface)
573             for method in interface.itermethods():
574                 for arg in method.args:
575                     collector.visit(arg.type)
576                 collector.visit(method.type)
577         return collector.types
578
579     def add_function(self, function):
580         self.functions.append(function)
581
582     def add_functions(self, functions):
583         for function in functions:
584             self.add_function(function)
585
586     def add_interface(self, interface):
587         self.interfaces.append(interface)
588
589     def add_interfaces(self, interfaces):
590         self.interfaces.extend(interfaces)
591
592     def add_api(self, api):
593         self.headers.extend(api.headers)
594         self.add_functions(api.functions)
595         self.add_interfaces(api.interfaces)
596
597     def get_function_by_name(self, name):
598         for function in self.functions:
599             if function.name == name:
600                 return function
601         return None
602
603
604 Bool = Literal("bool", "Bool")
605 SChar = Literal("signed char", "SInt")
606 UChar = Literal("unsigned char", "UInt")
607 Short = Literal("short", "SInt")
608 Int = Literal("int", "SInt")
609 Long = Literal("long", "SInt")
610 LongLong = Literal("long long", "SInt")
611 UShort = Literal("unsigned short", "UInt")
612 UInt = Literal("unsigned int", "UInt")
613 ULong = Literal("unsigned long", "UInt")
614 ULongLong = Literal("unsigned long long", "UInt")
615 Float = Literal("float", "Float")
616 Double = Literal("double", "Double")
617 SizeT = Literal("size_t", "UInt")
618 WString = Literal("wchar_t *", "WString")
619
620 Int8 = Literal("int8_t", "SInt")
621 UInt8 = Literal("uint8_t", "UInt")
622 Int16 = Literal("int16_t", "SInt")
623 UInt16 = Literal("uint16_t", "UInt")
624 Int32 = Literal("int32_t", "SInt")
625 UInt32 = Literal("uint32_t", "UInt")
626 Int64 = Literal("int64_t", "SInt")
627 UInt64 = Literal("uint64_t", "UInt")