mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice-protocol
synced 2025-12-27 15:08:16 +00:00
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>
This commit is contained in:
parent
77ce36426f
commit
e919337980
@ -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
|
||||
|
||||
@ -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])
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user