From: José Fonseca Date: Sat, 15 Oct 2011 12:17:26 +0000 (+0100) Subject: Distinguish between tags and ids. X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=02c2500281c9af1039c272874f38e7802c9acfb9;p=apitrace Distinguish between tags and ids. --- diff --git a/retrace.py b/retrace.py index 90a4414..22ce5ed 100644 --- a/retrace.py +++ b/retrace.py @@ -69,14 +69,14 @@ class ValueExtractor(stdapi.Visitor): self.visit(bitmask.type, lvalue, rvalue) def visit_array(self, array, lvalue, rvalue): - print ' const Trace::Array *__a%s = dynamic_cast(&%s);' % (array.id, rvalue) - print ' if (__a%s) {' % (array.id) - length = '__a%s->values.size()' % array.id + print ' const Trace::Array *__a%s = dynamic_cast(&%s);' % (array.tag, rvalue) + print ' if (__a%s) {' % (array.tag) + length = '__a%s->values.size()' % array.tag print ' %s = new %s[%s];' % (lvalue, array.type, length) - index = '__j' + array.id + index = '__j' + array.tag print ' for (size_t {i} = 0; {i} < {length}; ++{i}) {{'.format(i = index, length = length) try: - self.visit(array.type, '%s[%s]' % (lvalue, index), '*__a%s->values[%s]' % (array.id, index)) + self.visit(array.type, '%s[%s]' % (lvalue, index), '*__a%s->values[%s]' % (array.tag, index)) finally: print ' }' print ' } else {' @@ -84,11 +84,11 @@ class ValueExtractor(stdapi.Visitor): print ' }' def visit_pointer(self, pointer, lvalue, rvalue): - print ' const Trace::Array *__a%s = dynamic_cast(&%s);' % (pointer.id, rvalue) - print ' if (__a%s) {' % (pointer.id) + print ' const Trace::Array *__a%s = dynamic_cast(&%s);' % (pointer.tag, rvalue) + print ' if (__a%s) {' % (pointer.tag) print ' %s = new %s;' % (lvalue, pointer.type) try: - self.visit(pointer.type, '%s[0]' % (lvalue,), '*__a%s->values[0]' % (pointer.id,)) + self.visit(pointer.type, '%s[0]' % (lvalue,), '*__a%s->values[0]' % (pointer.tag,)) finally: print ' } else {' print ' %s = NULL;' % lvalue @@ -134,22 +134,22 @@ class ValueWrapper(stdapi.Visitor): pass def visit_array(self, array, lvalue, rvalue): - print ' const Trace::Array *__a%s = dynamic_cast(&%s);' % (array.id, rvalue) - print ' if (__a%s) {' % (array.id) - length = '__a%s->values.size()' % array.id - index = '__j' + array.id + print ' const Trace::Array *__a%s = dynamic_cast(&%s);' % (array.tag, rvalue) + print ' if (__a%s) {' % (array.tag) + length = '__a%s->values.size()' % array.tag + index = '__j' + array.tag print ' for (size_t {i} = 0; {i} < {length}; ++{i}) {{'.format(i = index, length = length) try: - self.visit(array.type, '%s[%s]' % (lvalue, index), '*__a%s->values[%s]' % (array.id, index)) + self.visit(array.type, '%s[%s]' % (lvalue, index), '*__a%s->values[%s]' % (array.tag, index)) finally: print ' }' print ' }' def visit_pointer(self, pointer, lvalue, rvalue): - print ' const Trace::Array *__a%s = dynamic_cast(&%s);' % (pointer.id, rvalue) - print ' if (__a%s) {' % (pointer.id) + print ' const Trace::Array *__a%s = dynamic_cast(&%s);' % (pointer.tag, rvalue) + print ' if (__a%s) {' % (pointer.tag) try: - self.visit(pointer.type, '%s[0]' % (lvalue,), '*__a%s->values[0]' % (pointer.id,)) + self.visit(pointer.type, '%s[0]' % (lvalue,), '*__a%s->values[0]' % (pointer.tag,)) finally: print ' }' @@ -164,7 +164,7 @@ class ValueWrapper(stdapi.Visitor): print ' std::cout << "{handle.name} " << {rvalue} << " -> " << {lvalue} << "\\n";'.format(**locals()) print ' }' else: - i = '__h' + handle.id + i = '__h' + handle.tag lvalue = "%s + %s" % (lvalue, i) rvalue = "__orig_result + %s" % (i,) entry = handle_entry(handle, rvalue) diff --git a/specs/stdapi.py b/specs/stdapi.py index 11b1eef..7044c38 100644 --- a/specs/stdapi.py +++ b/specs/stdapi.py @@ -30,28 +30,36 @@ import debug class Type: + """Base class for all types.""" - __all = {} - __seq = 0 + __tags = set() - def __init__(self, expr, id = ''): + def __init__(self, expr, tag = None): self.expr = expr - - for char in id: - assert char.isalnum() or char in '_ ' - id = id.replace(' ', '_') - - if id in Type.__all: - Type.__seq += 1 - id += str(Type.__seq) - - assert id not in Type.__all - Type.__all[id] = self + # Generate a default tag, used when naming functions that will operate + # on this type, so it should preferrably be something representative of + # the type. + if tag is None: + tag = ''.join([c for c in expr if c.isalnum() or c in '_']) + else: + for c in tag: + assert c.isalnum() or c in '_' + + # Ensure it is unique. + if tag in Type.__tags: + suffix = 1 + while tag + str(suffix) in Type.__tags: + suffix += 1 + tag += str(suffix) - self.id = id + assert tag not in Type.__tags + Type.__tags.add(tag) + + self.tag = tag def __str__(self): + """Return the C/C++ type expression for this type.""" return self.expr def visit(self, visitor, *args, **kwargs): @@ -60,6 +68,7 @@ class Type: class _Void(Type): + """Singleton void type.""" def __init__(self): Type.__init__(self, "void") @@ -96,7 +105,7 @@ class Const(Type): # The most legible expr = "const " + type.expr - Type.__init__(self, expr, 'C' + type.id) + Type.__init__(self, expr, 'C' + type.tag) self.type = type @@ -107,7 +116,7 @@ class Const(Type): class Pointer(Type): def __init__(self, type): - Type.__init__(self, type.expr + " *", 'P' + type.id) + Type.__init__(self, type.expr + " *", 'P' + type.tag) self.type = type def visit(self, visitor, *args, **kwargs): @@ -117,7 +126,7 @@ class Pointer(Type): class Handle(Type): def __init__(self, name, type, range=None, key=None): - Type.__init__(self, type.expr, 'P' + type.id) + Type.__init__(self, type.expr, 'P' + type.tag) self.name = name self.type = type self.range = range @@ -133,10 +142,16 @@ def ConstPointer(type): class Enum(Type): + __id = 0 + def __init__(self, name, values): Type.__init__(self, name) + + self.id = Enum.__id + Enum.__id += 1 + self.values = list(values) - + def visit(self, visitor, *args, **kwargs): return visitor.visit_enum(self, *args, **kwargs) @@ -147,8 +162,14 @@ def FakeEnum(type, values): class Bitmask(Type): + __id = 0 + def __init__(self, type, values): Type.__init__(self, type.expr) + + self.id = Bitmask.__id + Bitmask.__id += 1 + self.type = type self.values = values @@ -182,8 +203,14 @@ class Blob(Type): class Struct(Type): + __id = 0 + def __init__(self, name, members): Type.__init__(self, name) + + self.id = Struct.__id + Struct.__id += 1 + self.name = name self.members = members diff --git a/trace.py b/trace.py index 68cfa2d..5b8f7ec 100644 --- a/trace.py +++ b/trace.py @@ -52,13 +52,13 @@ class DumpDeclarator(stdapi.OnceVisitor): def visit_struct(self, struct): for type, name in struct.members: self.visit(type) - print 'static void __traceStruct%s(const %s &value) {' % (struct.id, struct.expr) + print 'static void __traceStruct%s(const %s &value) {' % (struct.tag, struct.expr) print ' static const char * members[%u] = {' % (len(struct.members),) for type, name, in struct.members: print ' "%s",' % (name,) print ' };' print ' static const Trace::StructSig sig = {' - print ' %u, "%s", %u, members' % (int(struct.id), struct.name, len(struct.members)) + print ' %u, "%s", %u, members' % (struct.id, struct.name, len(struct.members)) print ' };' print ' Trace::localWriter.beginStruct(&sig);' for type, name in struct.members: @@ -76,7 +76,7 @@ class DumpDeclarator(stdapi.OnceVisitor): __enum_id = 0 def visit_enum(self, enum): - print 'static void __traceEnum%s(const %s value) {' % (enum.id, enum.expr) + print 'static void __traceEnum%s(const %s value) {' % (enum.tag, enum.expr) n = len(enum.values) for i in range(n): value = enum.values[i] @@ -98,13 +98,13 @@ class DumpDeclarator(stdapi.OnceVisitor): print def visit_bitmask(self, bitmask): - print 'static const Trace::BitmaskFlag __bitmask%s_flags[] = {' % (bitmask.id) + print 'static const Trace::BitmaskFlag __bitmask%s_flags[] = {' % (bitmask.tag) for value in bitmask.values: print ' {"%s", %s},' % (value, value) print '};' print - print 'static const Trace::BitmaskSig __bitmask%s_sig = {' % (bitmask.id) - print ' %u, %u, __bitmask%s_flags' % (int(bitmask.id), len(bitmask.values), bitmask.id) + print 'static const Trace::BitmaskSig __bitmask%s_sig = {' % (bitmask.tag) + print ' %u, %u, __bitmask%s_flags' % (bitmask.id, len(bitmask.values), bitmask.tag) print '};' print @@ -136,7 +136,7 @@ class DumpDeclarator(stdapi.OnceVisitor): print def visit_polymorphic(self, polymorphic): - print 'static void __tracePolymorphic%s(int selector, const %s & value) {' % (polymorphic.id, polymorphic.expr) + print 'static void __tracePolymorphic%s(int selector, const %s & value) {' % (polymorphic.tag, polymorphic.expr) print ' switch (selector) {' for cases, type in polymorphic.iterswitch(): for case in cases: @@ -164,11 +164,11 @@ class DumpImplementer(stdapi.Visitor): self.visit(const.type, instance) def visit_struct(self, struct, instance): - print ' __traceStruct%s(%s);' % (struct.id, instance) + print ' __traceStruct%s(%s);' % (struct.tag, instance) def visit_array(self, array, instance): - length = '__c' + array.type.id - index = '__i' + array.type.id + length = '__c' + array.type.tag + index = '__i' + array.type.tag print ' if (%s) {' % instance print ' size_t %s = %s;' % (length, array.length) print ' Trace::localWriter.beginArray(%s);' % length @@ -186,10 +186,10 @@ class DumpImplementer(stdapi.Visitor): print ' Trace::localWriter.writeBlob(%s, %s);' % (instance, blob.size) def visit_enum(self, enum, instance): - print ' __traceEnum%s(%s);' % (enum.id, instance) + print ' __traceEnum%s(%s);' % (enum.tag, instance) def visit_bitmask(self, bitmask, instance): - print ' Trace::localWriter.writeBitmask(&__bitmask%s_sig, %s);' % (bitmask.id, instance) + print ' Trace::localWriter.writeBitmask(&__bitmask%s_sig, %s);' % (bitmask.tag, instance) def visit_pointer(self, pointer, instance): print ' if (%s) {' % instance @@ -215,7 +215,7 @@ class DumpImplementer(stdapi.Visitor): print ' Trace::localWriter.writeOpaque((const void *)&%s);' % instance def visit_polymorphic(self, polymorphic, instance): - print ' __tracePolymorphic%s(%s, %s);' % (polymorphic.id, polymorphic.switch_expr, instance) + print ' __tracePolymorphic%s(%s, %s);' % (polymorphic.tag, polymorphic.switch_expr, instance) dump_instance = DumpImplementer().visit @@ -340,7 +340,7 @@ class Tracer: print 'static const char * __%s_args[%u] = {%s};' % (function.name, len(function.args), ', '.join(['"%s"' % arg.name for arg in function.args])) else: print 'static const char ** __%s_args = NULL;' % (function.name,) - print 'static const Trace::FunctionSig __%s_sig = {%u, "%s", %u, __%s_args};' % (function.name, int(function.id), function.name, len(function.args), function.name) + print 'static const Trace::FunctionSig __%s_sig = {%u, "%s", %u, __%s_args};' % (function.name, function.id, function.name, len(function.args), function.name) print def is_public_function(self, function): @@ -426,7 +426,7 @@ class Tracer: def trace_method(self, interface, method): print method.prototype(interface_wrap_name(interface) + '::' + method.name) + ' {' print ' static const char * __args[%u] = {%s};' % (len(method.args) + 1, ', '.join(['"this"'] + ['"%s"' % arg.name for arg in method.args])) - print ' static const Trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (int(method.id), interface.name + '::' + method.name, len(method.args) + 1) + print ' static const Trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (method.id, interface.name + '::' + method.name, len(method.args) + 1) print ' unsigned __call = Trace::localWriter.beginEnter(&__sig);' print ' Trace::localWriter.beginArg(0);' print ' Trace::localWriter.writeOpaque((const void *)m_pInstance);'