]> git.cworth.org Git - apitrace/blob - stdapi.py
Put license in a separate file.
[apitrace] / 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
87         if type.expr.startswith("const "):
88             expr = type.expr + " const"
89         else:
90             expr = "const " + type.expr
91
92         Type.__init__(self, expr, 'C' + type.id)
93
94         self.type = type
95
96     def visit(self, visitor, *args, **kwargs):
97         return visitor.visit_const(self, *args, **kwargs)
98
99
100 class Pointer(Type):
101
102     def __init__(self, type):
103         Type.__init__(self, type.expr + " *", 'P' + type.id)
104         self.type = type
105
106     def visit(self, visitor, *args, **kwargs):
107         return visitor.visit_pointer(self, *args, **kwargs)
108
109
110 class Handle(Type):
111
112     def __init__(self, name, type, range=None, key=None):
113         Type.__init__(self, type.expr, 'P' + type.id)
114         self.name = name
115         self.type = type
116         self.range = range
117         self.key = key
118
119     def visit(self, visitor, *args, **kwargs):
120         return visitor.visit_handle(self, *args, **kwargs)
121
122
123 def ConstPointer(type):
124     return Pointer(Const(type))
125
126
127 class Enum(Type):
128
129     def __init__(self, name, values):
130         Type.__init__(self, name)
131         self.values = list(values)
132     
133     def visit(self, visitor, *args, **kwargs):
134         return visitor.visit_enum(self, *args, **kwargs)
135
136
137 def FakeEnum(type, values):
138     return Enum(type.expr, values)
139
140
141 class Bitmask(Type):
142
143     def __init__(self, type, values):
144         Type.__init__(self, type.expr)
145         self.type = type
146         self.values = values
147
148     def visit(self, visitor, *args, **kwargs):
149         return visitor.visit_bitmask(self, *args, **kwargs)
150
151 Flags = Bitmask
152
153
154 class Array(Type):
155
156     def __init__(self, type, length):
157         Type.__init__(self, type.expr + " *")
158         self.type = type
159         self.length = length
160
161     def visit(self, visitor, *args, **kwargs):
162         return visitor.visit_array(self, *args, **kwargs)
163
164
165 class Blob(Type):
166
167     def __init__(self, type, size):
168         Type.__init__(self, type.expr + ' *')
169         self.type = type
170         self.size = size
171
172     def visit(self, visitor, *args, **kwargs):
173         return visitor.visit_blob(self, *args, **kwargs)
174
175
176 class Struct(Type):
177
178     def __init__(self, name, members):
179         Type.__init__(self, name)
180         self.name = name
181         self.members = members
182
183     def visit(self, visitor, *args, **kwargs):
184         return visitor.visit_struct(self, *args, **kwargs)
185
186
187 class Alias(Type):
188
189     def __init__(self, expr, type):
190         Type.__init__(self, expr)
191         self.type = type
192
193     def visit(self, visitor, *args, **kwargs):
194         return visitor.visit_alias(self, *args, **kwargs)
195
196
197 def Out(type, name):
198     arg = Arg(type, name, output=True)
199     return arg
200
201
202 class Arg:
203
204     def __init__(self, type, name, output=False):
205         self.type = type
206         self.name = name
207         self.output = output
208         self.index = None
209
210     def __str__(self):
211         return '%s %s' % (self.type, self.name)
212
213
214 class Function:
215
216     __id = 0
217
218     def __init__(self, type, name, args, call = '', fail = None, sideeffects=True):
219         self.id = Function.__id
220         Function.__id += 1
221
222         self.type = type
223         self.name = name
224
225         self.args = []
226         index = 0
227         for arg in args:
228             if isinstance(arg, tuple):
229                 arg_type, arg_name = arg
230                 arg = Arg(arg_type, arg_name)
231             arg.index = index
232             index += 1
233             self.args.append(arg)
234
235         self.call = call
236         self.fail = fail
237         self.sideeffects = sideeffects
238
239     def prototype(self, name=None):
240         if name is not None:
241             name = name.strip()
242         else:
243             name = self.name
244         s = name
245         if self.call:
246             s = self.call + ' ' + s
247         if name.startswith('*'):
248             s = '(' + s + ')'
249         s = self.type.expr + ' ' + s
250         s += "("
251         if self.args:
252             s += ", ".join(["%s %s" % (arg.type, arg.name) for arg in self.args])
253         else:
254             s += "void"
255         s += ")"
256         return s
257
258
259 def StdFunction(*args, **kwargs):
260     kwargs.setdefault('call', '__stdcall')
261     return Function(*args, **kwargs)
262
263
264 def FunctionPointer(type, name, args, **kwargs):
265     # XXX: We should probably treat function pointers (callbacks or not) in a generic fashion
266     return Opaque(name)
267
268
269 class Interface(Type):
270
271     def __init__(self, name, base=None):
272         Type.__init__(self, name)
273         self.name = name
274         self.base = base
275         self.methods = []
276
277     def visit(self, visitor, *args, **kwargs):
278         return visitor.visit_interface(self, *args, **kwargs)
279
280     def itermethods(self):
281         if self.base is not None:
282             for method in self.base.itermethods():
283                 yield method
284         for method in self.methods:
285             yield method
286         raise StopIteration
287
288
289 class Method(Function):
290
291     def __init__(self, type, name, args):
292         Function.__init__(self, type, name, args, call = '__stdcall')
293         for index in range(len(self.args)):
294             self.args[index].index = index + 1
295
296
297 def WrapPointer(type):
298     return Pointer(type)
299
300
301 class String(Type):
302
303     def __init__(self, expr = "char *", length = None):
304         Type.__init__(self, expr)
305         self.length = length
306
307     def visit(self, visitor, *args, **kwargs):
308         return visitor.visit_string(self, *args, **kwargs)
309
310 # C string (i.e., zero terminated)
311 CString = String()
312
313
314 class Opaque(Type):
315     '''Opaque pointer.'''
316
317     def __init__(self, expr):
318         Type.__init__(self, expr)
319
320     def visit(self, visitor, *args, **kwargs):
321         return visitor.visit_opaque(self, *args, **kwargs)
322
323
324 def OpaquePointer(type, *args):
325     return Opaque(type.expr + ' *')
326
327 def OpaqueArray(type, size):
328     return Opaque(type.expr + ' *')
329
330 def OpaqueBlob(type, size):
331     return Opaque(type.expr + ' *')
332
333
334 class Visitor:
335
336     def visit(self, type, *args, **kwargs):
337         return type.visit(self, *args, **kwargs)
338
339     def visit_void(self, void, *args, **kwargs):
340         raise NotImplementedError
341
342     def visit_literal(self, literal, *args, **kwargs):
343         raise NotImplementedError
344
345     def visit_string(self, string, *args, **kwargs):
346         raise NotImplementedError
347
348     def visit_const(self, const, *args, **kwargs):
349         raise NotImplementedError
350
351     def visit_struct(self, struct, *args, **kwargs):
352         raise NotImplementedError
353
354     def visit_array(self, array, *args, **kwargs):
355         raise NotImplementedError
356
357     def visit_blob(self, blob, *args, **kwargs):
358         raise NotImplementedError
359
360     def visit_enum(self, enum, *args, **kwargs):
361         raise NotImplementedError
362
363     def visit_bitmask(self, bitmask, *args, **kwargs):
364         raise NotImplementedError
365
366     def visit_pointer(self, pointer, *args, **kwargs):
367         raise NotImplementedError
368
369     def visit_handle(self, handle, *args, **kwargs):
370         raise NotImplementedError
371
372     def visit_alias(self, alias, *args, **kwargs):
373         raise NotImplementedError
374
375     def visit_opaque(self, opaque, *args, **kwargs):
376         raise NotImplementedError
377
378     def visit_interface(self, interface, *args, **kwargs):
379         raise NotImplementedError
380
381
382 class OnceVisitor(Visitor):
383
384     def __init__(self):
385         self.__visited = set()
386
387     def visit(self, type, *args, **kwargs):
388         if type not in self.__visited:
389             self.__visited.add(type)
390             return type.visit(self, *args, **kwargs)
391         return None
392
393
394 class Rebuilder(Visitor):
395
396     def visit_void(self, void):
397         return void
398
399     def visit_literal(self, literal):
400         return literal
401
402     def visit_string(self, string):
403         return string
404
405     def visit_const(self, const):
406         return Const(const.type)
407
408     def visit_struct(self, struct):
409         members = [(self.visit(type), name) for type, name in struct.members]
410         return Struct(struct.name, members)
411
412     def visit_array(self, array):
413         type = self.visit(array.type)
414         return Array(type, array.length)
415
416     def visit_blob(self, blob):
417         type = self.visit(blob.type)
418         return Blob(type, blob.size)
419
420     def visit_enum(self, enum):
421         return enum
422
423     def visit_bitmask(self, bitmask):
424         type = self.visit(bitmask.type)
425         return Bitmask(type, bitmask.values)
426
427     def visit_pointer(self, pointer):
428         type = self.visit(pointer.type)
429         return Pointer(type)
430
431     def visit_handle(self, handle):
432         type = self.visit(handle.type)
433         return Handle(handle.name, type, range=handle.range, key=handle.key)
434
435     def visit_alias(self, alias):
436         type = self.visit(alias.type)
437         return Alias(alias.expr, type)
438
439     def visit_opaque(self, opaque):
440         return opaque
441
442
443 class Collector(Visitor):
444     '''Collect.'''
445
446     def __init__(self):
447         self.__visited = set()
448         self.types = []
449
450     def visit(self, type):
451         if type in self.__visited:
452             return
453         self.__visited.add(type)
454         Visitor.visit(self, type)
455         self.types.append(type)
456
457     def visit_void(self, literal):
458         pass
459
460     def visit_literal(self, literal):
461         pass
462
463     def visit_string(self, string):
464         pass
465
466     def visit_const(self, const):
467         self.visit(const.type)
468
469     def visit_struct(self, struct):
470         for type, name in struct.members:
471             self.visit(type)
472
473     def visit_array(self, array):
474         self.visit(array.type)
475
476     def visit_blob(self, array):
477         pass
478
479     def visit_enum(self, enum):
480         pass
481
482     def visit_bitmask(self, bitmask):
483         self.visit(bitmask.type)
484
485     def visit_pointer(self, pointer):
486         self.visit(pointer.type)
487
488     def visit_handle(self, handle):
489         self.visit(handle.type)
490
491     def visit_alias(self, alias):
492         self.visit(alias.type)
493
494     def visit_opaque(self, opaque):
495         pass
496
497     def visit_interface(self, interface):
498         if interface.base is not None:
499             self.visit(interface.base)
500         for method in interface.itermethods():
501             for arg in method.args:
502                 self.visit(arg.type)
503             self.visit(method.type)
504
505
506 class API:
507
508     def __init__(self, name = None):
509         self.name = name
510         self.headers = []
511         self.functions = []
512         self.interfaces = []
513
514     def all_types(self):
515         collector = Collector()
516         for function in self.functions:
517             for arg in function.args:
518                 collector.visit(arg.type)
519             collector.visit(function.type)
520         for interface in self.interfaces:
521             collector.visit(interface)
522             for method in interface.itermethods():
523                 for arg in method.args:
524                     collector.visit(arg.type)
525                 collector.visit(method.type)
526         return collector.types
527
528     def add_function(self, function):
529         self.functions.append(function)
530
531     def add_functions(self, functions):
532         for function in functions:
533             self.add_function(function)
534
535     def add_interface(self, interface):
536         self.interfaces.append(interface)
537
538     def add_interfaces(self, interfaces):
539         self.interfaces.extend(interfaces)
540
541     def add_api(self, api):
542         self.headers.extend(api.headers)
543         self.add_functions(api.functions)
544         self.add_interfaces(api.interfaces)
545
546     def get_function_by_name(self, name):
547         for function in self.functions:
548             if function.name == name:
549                 return function
550         return None
551
552
553 Bool = Literal("bool", "Bool")
554 SChar = Literal("signed char", "SInt")
555 UChar = Literal("unsigned char", "UInt")
556 Short = Literal("short", "SInt")
557 Int = Literal("int", "SInt")
558 Long = Literal("long", "SInt")
559 LongLong = Literal("long long", "SInt")
560 UShort = Literal("unsigned short", "UInt")
561 UInt = Literal("unsigned int", "UInt")
562 ULong = Literal("unsigned long", "UInt")
563 ULongLong = Literal("unsigned long long", "UInt")
564 Float = Literal("float", "Float")
565 Double = Literal("double", "Double")
566 SizeT = Literal("size_t", "UInt")
567 WString = Literal("wchar_t *", "WString")
568
569 Int8 = Literal("int8_t", "SInt")
570 UInt8 = Literal("uint8_t", "UInt")
571 Int16 = Literal("int16_t", "SInt")
572 UInt16 = Literal("uint16_t", "UInt")
573 Int32 = Literal("int32_t", "SInt")
574 UInt32 = Literal("uint32_t", "UInt")
575 Int64 = Literal("int64_t", "SInt")
576 UInt64 = Literal("uint64_t", "UInt")