]> git.cworth.org Git - apitrace/commitdiff
Improvements in AttribArray / attrib/list code generation.
authorAndreas Hartmetz <ahartmetz@gmail.com>
Tue, 9 Jul 2013 20:43:15 +0000 (22:43 +0200)
committerAndreas Hartmetz <ahartmetz@gmail.com>
Tue, 9 Jul 2013 20:46:00 +0000 (22:46 +0200)
- Treat unknown keys the same way while counting elements and while
  processing them (they are assumed to be followed by an int value).
- Support custom terminators.
- Serialize the terminator.
- Reduce the line count of generated code a bit.
- Add forgotten begin/endElement() around writing the keys.
- Improve comment wording.

wrappers/trace.py

index 17e4e9c9baf03a0158dbc4ebf02ee6a3afdd02f8..0d7741eb391e55ef5c6d51ef0429d7b206ef8ae3 100644 (file)
@@ -207,50 +207,58 @@ class ValueSerializer(stdapi.Visitor, stdapi.ExpanderMixin):
         print '    }'
 
     def visitAttribArray(self, array, instance):
-        # iterate element by element and for each, decide if it is a key or value (which depends on the
-        # previous key). If it is a value, look up what it means and store it as the right type - usually
-        # int, some bitfield, or some enum.
+        # For each element, decide if it is a key or a value (which depends on the previous key).
+        # If it is a value, store it as the right type - usually int, some bitfield, or some enum.
+        # It is currently assumed that an unknown key means that it is followed by an int value.
 
-        # determine the array length, which is unfortunately needed by writeArray() up front
+        # determine the array length which must be passed to writeArray() up front
         count = '_c' + array.keyType.tag
         print '    int %s;' % count
-        print '    for (%(c)s = 0; %(array)s && %(array)s[%(c)s]; %(c)s++) {' % {'c': count, 'array': instance}
-        print '        switch (%(array)s[%(c)s]) {' % {'array': instance, 'c': count}
-        for key, valueType in array.valueTypes:
-            if valueType is not None:
-                print '        case %s:' % key
-        print '            %s++;' % count # only a null key marks the end; skip null values
-        print '            break;'
-        print '        }'
+        print '    for (%(c)s = 0; %(array)s && %(array)s[%(c)s] != %(terminator)s; %(c)s += 2) {' \
+              % {'c': count, 'array': instance, 'terminator': array.terminator}
+        if array.hasKeysWithoutValues:
+            print '        switch (%(array)s[%(c)s]) {' % {'array': instance, 'c': count}
+            for key, valueType in array.valueTypes:
+                if valueType is None:
+                    print '        case %s:' % key
+            print '            %s--;' % count # the next value is a key again and checked if it's the terminator
+            print '            break;'
+            print '        }'
         print '    }'
-        # ### not handling null attrib_list differently from empty
+        print '    %(c)s += %(array)s ? 1 : 0;' % {'c': count, 'array': instance}
         print '    trace::localWriter.beginArray(%s);' % count
 
         # for each key / key-value pair write the key and the value, if the key requires one
 
         index = '_i' + array.keyType.tag
         print '    for (int %(i)s = 0; %(i)s < %(count)s; %(i)s++) {' % {'i': index, 'count': count}
+        print '        trace::localWriter.beginElement();'
         self.visitEnum(array.keyType, "%(array)s[%(i)s]" % {'array': instance, 'i': index})
-        print '        switch (%(array)s[%(i)s]) {' % {'array': instance, 'i': index}
+        print '        trace::localWriter.endElement();'
+        print '        if (%(i)s + 1 >= %(count)s) {' % {'i': index, 'count': count}
+        print '            break;'
+        print '        }'
+        print '        switch (%(array)s[%(i)s++]) {' % {'array': instance, 'i': index}
         # write generic value the usual way
         for key, valueType in array.valueTypes:
             if valueType is not None:
                 print '        case %s:' % key
-                print '            %s++;' % index
                 print '            trace::localWriter.beginElement();'
                 self.visitElement(index, valueType, '(%(array)s)[%(i)s]' % {'array': instance, 'i': index})
                 print '            trace::localWriter.endElement();'
                 print '            break;'
+        # known key with no value, just decrease the index so we treat the next value as a key
+        if array.hasKeysWithoutValues:
+            for key, valueType in array.valueTypes:
+                if valueType is None:
+                    print '        case %s:' % key
+            print '            %s--;' % index
+            print '            break;'
         # unknown key, write an int value
         print '        default:'
-        print '            %s++;' % index
         print '            trace::localWriter.beginElement();'
         print '            trace::localWriter.writeSInt(%(array)s[%(i)s]);'  % {'array': instance, 'i': index}
         print '            trace::localWriter.endElement();'
-        # known key with no value, do nothing
-        for key, valueType in array.valueTypes:
-            if valueType is None:
-                print '        case %s:' % key
         print '            break;'
         print '        }'
         print '    }'