From b491f9b5da9ccc5ed9ea831961df734a1137470e Mon Sep 17 00:00:00 2001 From: Andreas Hartmetz Date: Tue, 9 Jul 2013 22:43:15 +0200 Subject: [PATCH 1/1] Improvements in AttribArray / attrib/list code generation. - 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 | 48 +++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/wrappers/trace.py b/wrappers/trace.py index 17e4e9c..0d7741e 100644 --- a/wrappers/trace.py +++ b/wrappers/trace.py @@ -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 ' }' -- 2.43.0