diff options
author | Alexander Wauck <awauck@codeweavers.com> | 2015-03-31 12:44:09 -0500 |
---|---|---|
committer | Christophe Fergeau <cfergeau@redhat.com> | 2015-04-01 13:39:03 +0200 |
commit | e919337980c45fb4bc907cf40cdd106fb8f32d92 (patch) | |
tree | 066ce443b361eff8533f717c5c0b134187c08321 | |
parent | 77ce36426f26cd3dcf8bb06a0511f365c74003dc (diff) |
Make spice_codegen.py work on both Python 2 and 3
This is a new version of my previous patch that does not include six.py.
It's still kind of big, but at least it's all spice-common changes now.
There are also a few other fixes that Christophe brought to my attention.
Note that six now needs to be installed on the system (python-six on
Fedora and Debian, six on PyPI).
This *should* be enough to make spice_codegen.py work on both Python 2
and Python 3. The major changes are as follows:
* cStringIO.StringIO -> io.StringIO
* str vs. unicode updates (io.StringIO doesn't like str)
* integer division
* foo.has_key(bar) -> bar in foo
* import internal_thing -> from . import internal_thing
* removed from __future__ import with_statement
(might break Python 2.5?)
* changed some lambdas to list comprehensions (done by 2to3)
* cast some_dict.keys() to list where needed (e.g. for sorting)
* use normal type names with isinstance instead of types.WhateverType
Signed-off-by: Alexander Wauck <awauck@codeweavers.com>
-rw-r--r-- | python_modules/codegen.py | 28 | ||||
-rw-r--r-- | python_modules/demarshal.py | 12 | ||||
-rw-r--r-- | python_modules/marshal.py | 18 | ||||
-rw-r--r-- | python_modules/ptypes.py | 66 | ||||
-rw-r--r-- | python_modules/spice_parser.py | 13 | ||||
-rwxr-xr-x | spice_codegen.py | 10 |
6 files changed, 78 insertions, 69 deletions
diff --git a/python_modules/codegen.py b/python_modules/codegen.py index 009cf95..55f513b 100644 --- a/python_modules/codegen.py +++ b/python_modules/codegen.py @@ -1,5 +1,6 @@ -from __future__ import with_statement -from cStringIO import StringIO + +import six +from io import StringIO def camel_to_underscores(s, upper = False): res = "" @@ -85,10 +86,10 @@ class CodeWriter: self.options[opt] = value def has_option(self, opt): - return self.options.has_key(opt) + return opt in self.options def set_is_generated(self, kind, name): - if not self.generated.has_key(kind): + if kind not in self.generated: v = {} self.generated[kind] = v else: @@ -96,13 +97,13 @@ class CodeWriter: v[name] = 1 def is_generated(self, kind, name): - if not self.generated.has_key(kind): + if kind not in self.generated: return False v = self.generated[kind] - return v.has_key(name) + return name in v def getvalue(self): - strs = map(lambda writer: writer.getvalue(), self.contents) + strs = [writer.getvalue() for writer in self.contents] return "".join(strs) def get_subwriter(self): @@ -119,21 +120,24 @@ class CodeWriter: return writer def write(self, s): - # Ensure its a string - s = str(s) + # Ensure its a unicode string + if six.PY2: + s = unicode(s) + else: + s = str(s) if len(s) == 0: return if self.at_line_start: for i in range(self.indentation): - self.out.write(" ") + self.out.write(u" ") self.at_line_start = False self.out.write(s) return self def newline(self): - self.out.write("\n") + self.out.write(u"\n") self.at_line_start = True return self @@ -341,7 +345,7 @@ class CodeWriter: self.indentation = indentation def add_function_variable(self, ctype, name): - if self.function_variables.has_key(name): + if name in self.function_variables: assert(self.function_variables[name] == ctype) else: self.function_variables[name] = ctype diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py index 109f5e6..209eafc 100644 --- a/python_modules/demarshal.py +++ b/python_modules/demarshal.py @@ -1,6 +1,6 @@ -from __future__ import with_statement -import ptypes -import codegen + +from . import ptypes +from . import codegen # The handling of sizes is somewhat complex, as there are several types of size: # * nw_size @@ -68,7 +68,7 @@ def write_parser_helpers(writer): scope = writer.function("SPICE_GNUC_UNUSED consume_%s" % type, ctype, "uint8_t **ptr", True) scope.variable_def(ctype, "val") writer.assign("val", "read_%s(*ptr)" % type) - writer.increment("*ptr", size / 8) + writer.increment("*ptr", size // 8) writer.statement("return val") writer.end_block() @@ -1119,7 +1119,7 @@ def write_channel_parser(writer, channel, server): ids2 = ids.copy() while len(ids2) > 0: end = start = min(ids2.keys()) - while ids2.has_key(end): + while end in ids2: del ids2[end] end = end + 1 @@ -1181,7 +1181,7 @@ def write_get_channel_parser(writer, channel_parsers, max_channel, is_server): writer.begin_block() channel = None for i in range(0, max_channel + 1): - if channel_parsers.has_key(i): + if i in channel_parsers: channel = channel_parsers[i][0] if channel.has_attr("ifdef"): writer.ifdef(channel.attributes["ifdef"][0]) diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 1eda1ba..b77b910 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -1,6 +1,6 @@ -from __future__ import with_statement -import ptypes -import codegen + +from . import ptypes +from . import codegen def write_includes(writer): writer.header.writeln("#include <spice/protocol.h>") @@ -112,7 +112,7 @@ def write_marshal_ptr_function(writer, target_type, is_helper=True): names = target_type.get_pointer_names(False) names_args = "" if len(names) > 0: - n = map(lambda name: ", SpiceMarshaller **%s_out" % name, names) + n = [", SpiceMarshaller **%s_out" % name for name in names] names_args = "".join(n) header = writer.header @@ -345,7 +345,7 @@ def write_message_marshaller(writer, message, is_server, private): names = message.get_pointer_names(False) names_args = "" if len(names) > 0: - n = map(lambda name: ", SpiceMarshaller **%s_out" % name, names) + n = [", SpiceMarshaller **%s_out" % name for name in names] names_args = "".join(n) if not private: @@ -383,9 +383,9 @@ def write_protocol_marshaller(writer, proto, is_server, private_marshallers): for m in channel.client_messages: message = m.message_type f = write_message_marshaller(writer, message, is_server, private_marshallers) - if channel.has_attr("ifdef") and not functions.has_key(f): + if channel.has_attr("ifdef") and f not in functions: functions[f] = channel.attributes["ifdef"][0] - elif message.has_attr("ifdef") and not functions.has_key(f): + elif message.has_attr("ifdef") and f not in functions: functions[f] = message.attributes["ifdef"][0] else: functions[f] = True @@ -393,9 +393,9 @@ def write_protocol_marshaller(writer, proto, is_server, private_marshallers): for m in channel.server_messages: message = m.message_type f = write_message_marshaller(writer, message, is_server, private_marshallers) - if channel.has_attr("ifdef") and not functions.has_key(f): + if channel.has_attr("ifdef") and f not in functions: functions[f] = channel.attributes["ifdef"][0] - elif message.has_attr("ifdef") and not functions.has_key(f): + elif message.has_attr("ifdef") and f not in functions: functions[f] = message.attributes["ifdef"][0] else: functions[f] = True diff --git a/python_modules/ptypes.py b/python_modules/ptypes.py index 2bfbf0d..d031d09 100644 --- a/python_modules/ptypes.py +++ b/python_modules/ptypes.py @@ -1,4 +1,4 @@ -import codegen +from . import codegen import types _types_by_name = {} @@ -7,7 +7,7 @@ _types = [] default_pointer_size = 4 def type_exists(name): - return _types_by_name.has_key(name) + return name in _types_by_name def lookup_type(name): return _types_by_name[name] @@ -24,7 +24,7 @@ class FixedSize: self.vals[minor] = val def __add__(self, other): - if isinstance(other, types.IntType): + if isinstance(other, int): other = FixedSize(other) new = FixedSize() @@ -125,13 +125,13 @@ class Type: if self.registred or self.name == None: return self.registred = True - if _types_by_name.has_key(self.name): - raise Exception, "Type %s already defined" % self.name + if self.name in _types_by_name: + raise Exception("Type %s already defined" % self.name) _types.append(self) _types_by_name[self.name] = self def has_attr(self, name): - return self.attributes.has_key(name) + return name in self.attributes class TypeRef(Type): def __init__(self, name): @@ -142,8 +142,8 @@ class TypeRef(Type): return "ref to %s" % (self.name) def resolve(self): - if not _types_by_name.has_key(self.name): - raise Exception, "Unknown type %s" % self.name + if self.name not in _types_by_name: + raise Exception("Unknown type %s" % self.name) return _types_by_name[self.name] def register(self): @@ -168,7 +168,7 @@ class IntegerType(Type): return self.name + "_t" def get_fixed_nw_size(self): - return self.bits / 8 + return self.bits // 8 def is_primitive(self): return True @@ -245,14 +245,14 @@ class EnumBaseType(Type): return True def get_fixed_nw_size(self): - return self.bits / 8 + return self.bits // 8 # generates a value-name table suitable for use with the wireshark protocol # dissector def c_describe(self, writer): writer.write("static const value_string %s_vs[] = " % codegen.prefix_underscore_lower(self.name)) writer.begin_block() - values = self.names.keys() + values = list(self.names.keys()) values.sort() for i in values: writer.write("{ ") @@ -281,7 +281,7 @@ class EnumType(EnumBaseType): value = last + 1 last = value - assert not names.has_key(value) + assert value not in names names[value] = name values[name] = value @@ -298,7 +298,7 @@ class EnumType(EnumBaseType): writer.write("typedef enum ") writer.write(self.c_name()) writer.begin_block() - values = self.names.keys() + values = list(self.names.keys()) values.sort() current_default = 0 for i in values: @@ -335,7 +335,7 @@ class FlagsType(EnumBaseType): value = last + 1 last = value - assert not names.has_key(value) + assert value not in names names[value] = name values[name] = value @@ -352,7 +352,7 @@ class FlagsType(EnumBaseType): writer.write("typedef enum ") writer.write(self.c_name()) writer.begin_block() - values = self.names.keys() + values = list(self.names.keys()) values.sort() mask = 0 for i in values: @@ -392,26 +392,26 @@ class ArrayType(Type): return self def is_constant_length(self): - return isinstance(self.size, types.IntType) + return isinstance(self.size, int) def is_remaining_length(self): - return isinstance(self.size, types.StringType) and len(self.size) == 0 + return isinstance(self.size, str) and len(self.size) == 0 def is_identifier_length(self): - return isinstance(self.size, types.StringType) and len(self.size) > 0 + return isinstance(self.size, str) and len(self.size) > 0 def is_image_size_length(self): - if isinstance(self.size, types.IntType) or isinstance(self.size, types.StringType): + if isinstance(self.size, int) or isinstance(self.size, str): return False return self.size[0] == "image_size" def is_bytes_length(self): - if isinstance(self.size, types.IntType) or isinstance(self.size, types.StringType): + if isinstance(self.size, int) or isinstance(self.size, str): return False return self.size[0] == "bytes" def is_cstring_length(self): - if isinstance(self.size, types.IntType) or isinstance(self.size, types.StringType): + if isinstance(self.size, int) or isinstance(self.size, str): return False return self.size[0] == "cstring" @@ -423,7 +423,7 @@ class ArrayType(Type): def get_fixed_nw_size(self): if not self.is_fixed_nw_size(): - raise Exception, "Not a fixed size type" + raise Exception("Not a fixed size type") return self.element_type.get_fixed_nw_size() * self.size @@ -433,13 +433,13 @@ class ArrayType(Type): return 0 if self.is_constant_length(self): return element_count * self.size - raise Exception, "Pointers in dynamic arrays not supported" + raise Exception("Pointers in dynamic arrays not supported") def get_pointer_names(self, marshalled): element_count = self.element_type.get_num_pointers() if element_count == 0: return [] - raise Exception, "Pointer names in arrays not supported" + raise Exception("Pointer names in arrays not supported") def is_extra_size(self): return self.has_attr("ptr_array") @@ -517,7 +517,7 @@ class Containee: return not self.is_switch() and self.member_type.is_primitive() def has_attr(self, name): - return self.attributes.has_key(name) + return name in self.attributes def has_minor_attr(self): return self.has_attr("minor") @@ -599,7 +599,7 @@ class Member(Containee): names = self.member_type.get_pointer_names(marshalled) if self.has_attr("outvar"): prefix = self.attributes["outvar"][0] - names = map(lambda name: prefix + "_" + name, names) + names = [prefix + "_" + name for name in names] return names class SwitchCase: @@ -656,7 +656,7 @@ class Switch(Containee): def resolve(self, container): self.container = container - self.cases = map(lambda c : c.resolve(self), self.cases) + self.cases = [c.resolve(self) for c in self.cases] return self def __repr__(self): @@ -703,7 +703,7 @@ class Switch(Containee): def get_fixed_nw_size(self): if not self.is_fixed_nw_size(): - raise Exception, "Not a fixed size type" + raise Exception("Not a fixed size type") size = 0 for c in self.cases: size = max(size, c.member.get_fixed_nw_size()) @@ -774,7 +774,7 @@ class ContainerType(Type): return size def resolve(self): - self.members = map(lambda m : m.resolve(self), self.members) + self.members = [m.resolve(self) for m in self.members] return self def get_num_pointers(self): @@ -819,7 +819,7 @@ class ContainerType(Type): name = name[:dot] member = None - if self.members_by_name.has_key(name): + if name in self.members_by_name: member = self.members_by_name[name] else: for m in self.members: @@ -831,7 +831,7 @@ class ContainerType(Type): break if member == None: - raise Exception, "No member called %s found" % name + raise Exception("No member called %s found" % name) if rest != None: return member.member_type.lookup_member(rest) @@ -880,7 +880,7 @@ class MessageType(ContainerType): def c_name(self): if self.name == None: - cms = self.reverse_members.keys() + cms = list(self.reverse_members.keys()) if len(cms) != 1: raise "Unknown typename for message" cm = cms[0] @@ -900,7 +900,7 @@ class MessageType(ContainerType): if self.has_attr("ctype"): return self.attributes["ctype"][0] if self.name == None: - cms = self.reverse_members.keys() + cms = list(self.reverse_members.keys()) if len(cms) != 1: raise "Unknown typename for message" cm = cms[0] diff --git a/python_modules/spice_parser.py b/python_modules/spice_parser.py index 44456ab..d60bb10 100644 --- a/python_modules/spice_parser.py +++ b/python_modules/spice_parser.py @@ -3,11 +3,12 @@ try: Forward, delimitedList, Group, Optional, Combine, alphas, nums, restOfLine, cStyleComment, \ alphanums, ParseException, ParseResults, Keyword, StringEnd, replaceWith except ImportError: - print "Module pyparsing not found." + six.print_("Module pyparsing not found.") exit(1) -import ptypes +from . import ptypes +import six import sys cvtInt = lambda toks: int(toks[0]) @@ -148,10 +149,10 @@ def parse(filename): try: bnf = SPICE_BNF() types = bnf.parseFile(filename) - except ParseException, err: - print >> sys.stderr, err.line - print >> sys.stderr, " "*(err.column-1) + "^" - print >> sys.stderr, err + except ParseException as err: + six.print_(err.line, file=sys.stderr) + six.print_(" "*(err.column-1) + "^", file=sys.stderr) + six.print_(err, file=sys.stderr) return None for t in types: diff --git a/spice_codegen.py b/spice_codegen.py index c8376cc..16ad478 100755 --- a/spice_codegen.py +++ b/spice_codegen.py @@ -9,6 +9,7 @@ from python_modules import ptypes from python_modules import codegen from python_modules import demarshal from python_modules import marshal +import six def write_channel_enums(writer, channel, client, describe): messages = filter(lambda m : m.channel == channel, \ @@ -257,15 +258,18 @@ if options.keep_identical_file: f.close() if content == old_content: - print "No changes to %s" % dest_file + six.print_("No changes to %s" % dest_file) sys.exit(0) except IOError: pass f = open(dest_file, 'wb') -f.write(content) +if six.PY2: + f.write(content) +else: + f.write(bytes(content, 'UTF-8')) f.close() -print "Wrote %s" % dest_file +six.print_("Wrote %s" % dest_file) sys.exit(0) |