From cf8b8cfede4562d8bd34bf18e8e0e49f16125c6f Mon Sep 17 00:00:00 2001 From: matthieu Date: Tue, 11 Sep 2018 19:31:11 +0000 Subject: [PATCH] Update to xcb-proto 1.13. ok tb@ --- proto/xcb-proto/NEWS | 11 +++ proto/xcb-proto/configure.ac | 2 +- proto/xcb-proto/doc/xml-xcb.txt | 29 +++++++ proto/xcb-proto/py-compile | 6 +- proto/xcb-proto/src/dri3.xml | 71 ++++++++++++++++- proto/xcb-proto/src/present.xml | 4 +- proto/xcb-proto/src/randr.xml | 67 ++++++++++++---- proto/xcb-proto/src/res.xml | 10 ++- proto/xcb-proto/src/xcb.xsd | 30 ++++++- proto/xcb-proto/src/xinput.xml | 81 ++++++++++--------- proto/xcb-proto/src/xproto.xml | 2 + proto/xcb-proto/xcbgen/align.py | 100 +++++++++++------------ proto/xcb-proto/xcbgen/expr.py | 1 + proto/xcb-proto/xcbgen/matcher.py | 7 ++ proto/xcb-proto/xcbgen/state.py | 41 ++++++++++ proto/xcb-proto/xcbgen/xtypes.py | 127 +++++++++++++++++++++++++++--- 16 files changed, 464 insertions(+), 125 deletions(-) diff --git a/proto/xcb-proto/NEWS b/proto/xcb-proto/NEWS index caf1ffad4..efae961ab 100644 --- a/proto/xcb-proto/NEWS +++ b/proto/xcb-proto/NEWS @@ -1,3 +1,14 @@ +Release 1.13 (2018-02-28) +========================= +* dri3: Add multi-plane/modifier protocol for v1.2 +* present: Add suboptimal-copy protocol for v1.2 +* randr: Add output-lease protocol for v1.6 +* Add support for variable-sized lists of FDs +* xge: Add safe generic-event sending support +* Fix initial connection handshaking +* Updated XML DTD +* Python 3.x cleanups and compatibility + Release 1.12 (2016-05-18) ========================= * xinput: Various padding-related additions and fixes diff --git a/proto/xcb-proto/configure.ac b/proto/xcb-proto/configure.ac index 540a8dd17..88b3439c9 100644 --- a/proto/xcb-proto/configure.ac +++ b/proto/xcb-proto/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ(2.57) AC_INIT([XCB Proto], - 1.12, + 1.13, [xcb@lists.freedesktop.org]) AC_CONFIG_SRCDIR([xcb-proto.pc.in]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) diff --git a/proto/xcb-proto/doc/xml-xcb.txt b/proto/xcb-proto/doc/xml-xcb.txt index 9cef1de11..f5b9aed13 100644 --- a/proto/xcb-proto/doc/xml-xcb.txt +++ b/proto/xcb-proto/doc/xml-xcb.txt @@ -76,6 +76,12 @@ Top-Level Elements the field and pad elements described in the section "Structure Contents below". +event-type-selector list + + This element represents a data structure that is the wire-representation of + an event. The event can be any type that's selected by the + event-type-selector list. + This element represents an identifier for a particular type of resource. @@ -359,6 +365,29 @@ Expressions This element represents the current list-element when used inside a list-iteration expression such as . + +Event-Type-Selector List +------------------------ + + The event-type-selector list selects a set of eventtypes. + It consists of any number of the following elements: + + + + The extension attribute selects events from the given extension. + + If the xge attribute is true, the event is an X Generic Event and + will be treated as such. + + opcode-min and opcode-max describe the minimum and maximum opcode + respectively. The opcode is the same number as the number-attribute + of an event definition. I.e. this is the offset from the event-base + to the actual number used on the wire. + + In the current implementation, only xge="false" is supported. + + Documentation ------------- diff --git a/proto/xcb-proto/py-compile b/proto/xcb-proto/py-compile index bc2039140..3693d96b0 100644 --- a/proto/xcb-proto/py-compile +++ b/proto/xcb-proto/py-compile @@ -1,9 +1,9 @@ #!/bin/sh # py-compile - Compile a Python program -scriptversion=2011-06-08.12; # UTC +scriptversion=2016-01-11.22; # UTC -# Copyright (C) 2000-2014 Free Software Foundation, Inc. +# Copyright (C) 2000-2017 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -165,6 +165,6 @@ sys.stdout.write('\n')" 2>/dev/null || : # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/proto/xcb-proto/src/dri3.xml b/proto/xcb-proto/src/dri3.xml index 608af3157..895d12a53 100644 --- a/proto/xcb-proto/src/dri3.xml +++ b/proto/xcb-proto/src/dri3.xml @@ -23,7 +23,7 @@ OF THIS SOFTWARE. --> + major-version="1" minor-version="2"> xproto @@ -94,4 +94,73 @@ OF THIS SOFTWARE. + + + + + + + + + + + + + + num_window_modifiers + + + num_screen_modifiers + + + + + + + + + + + + + + + + + + + + + + + + + + num_buffers + + + + + + + + + + + + + + + + + nfd + + + nfd + + + nfd + + + diff --git a/proto/xcb-proto/src/present.xml b/proto/xcb-proto/src/present.xml index a648ad77c..fb06e73f0 100644 --- a/proto/xcb-proto/src/present.xml +++ b/proto/xcb-proto/src/present.xml @@ -23,7 +23,7 @@ OF THIS SOFTWARE. --> + major-version="1" minor-version="2"> xproto randr xfixes @@ -51,6 +51,7 @@ OF THIS SOFTWARE. 0 1 2 + 3 @@ -69,6 +70,7 @@ OF THIS SOFTWARE. 0 1 2 + 3 diff --git a/proto/xcb-proto/src/randr.xml b/proto/xcb-proto/src/randr.xml index 722f715bf..703d6ba25 100644 --- a/proto/xcb-proto/src/randr.xml +++ b/proto/xcb-proto/src/randr.xml @@ -27,7 +27,7 @@ authorization from the authors. --> + major-version="1" minor-version="6"> xproto render @@ -37,6 +37,7 @@ authorization from the authors. + @@ -124,6 +125,7 @@ authorization from the authors. 4 5 6 + 7 @@ -798,6 +800,7 @@ authorization from the authors. 3 4 5 + 6 @@ -858,20 +861,6 @@ authorization from the authors. - - - - - - - - - - - - - - @@ -914,4 +903,52 @@ authorization from the authors. + + + + + + + + + + num_crtcs + + + num_outputs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proto/xcb-proto/src/res.xml b/proto/xcb-proto/src/res.xml index 17e6f833d..be32ca18b 100644 --- a/proto/xcb-proto/src/res.xml +++ b/proto/xcb-proto/src/res.xml @@ -55,7 +55,15 @@ authorization from the authors. - length + + + length + 4 + diff --git a/proto/xcb-proto/src/xcb.xsd b/proto/xcb-proto/src/xcb.xsd index c1dce3e1e..dc3d7cc18 100644 --- a/proto/xcb-proto/src/xcb.xsd +++ b/proto/xcb-proto/src/xcb.xsd @@ -44,6 +44,15 @@ authorization from the authors. + + + + + + + + + @@ -76,14 +85,13 @@ authorization from the authors. + - - @@ -201,6 +209,7 @@ authorization from the authors. + @@ -231,6 +240,22 @@ authorization from the authors. + + + + + + + + + + + + + + + @@ -345,6 +370,7 @@ authorization from the authors. + diff --git a/proto/xcb-proto/src/xinput.xml b/proto/xcb-proto/src/xinput.xml index 94855bac8..5f88a9857 100644 --- a/proto/xcb-proto/src/xinput.xml +++ b/proto/xcb-proto/src/xinput.xml @@ -32,27 +32,6 @@ authorization from the authors. http://cgit.freedesktop.org/xorg/proto/inputproto/tree/specs/XI2proto.txt --> - - - xfixes @@ -226,10 +205,11 @@ This affects the following: + - + @@ -986,25 +966,8 @@ This affects the following: - - - - - - - - - - - - num_events - 32 - - - - num_classes - - + @@ -2641,6 +2604,42 @@ This affects the following: + + + + + + + + + + + + + + + + + num_events + + + num_classes + + + + diff --git a/proto/xcb-proto/src/xproto.xml b/proto/xcb-proto/src/xproto.xml index 437dc30af..dea48dfed 100644 --- a/proto/xcb-proto/src/xproto.xml +++ b/proto/xcb-proto/src/xproto.xml @@ -198,9 +198,11 @@ authorization from the authors. authorization_protocol_name_len + authorization_protocol_data_len + diff --git a/proto/xcb-proto/xcbgen/align.py b/proto/xcb-proto/xcbgen/align.py index 5e3183801..d4c12ee40 100644 --- a/proto/xcb-proto/xcbgen/align.py +++ b/proto/xcb-proto/xcbgen/align.py @@ -16,12 +16,12 @@ class Alignment(object): return self.align == other.align and self.offset == other.offset def __str__(self): - return "(align=%d, offset=%d)" % (self.align, self.offset) + return "(align=%d, offset=%d)" % (self.align, self.offset) @staticmethod def for_primitive_type(size): - # compute the required start_alignment based on the size of the type - if size % 8 == 0: + # compute the required start_alignment based on the size of the type + if size % 8 == 0: # do 8-byte primitives require 8-byte alignment in X11? return Alignment(8,0) elif size % 4 == 0: @@ -33,7 +33,7 @@ class Alignment(object): def align_after_fixed_size(self, size): - new_offset = (self.offset + size) % self.align + new_offset = (self.offset + size) % self.align return Alignment(self.align, new_offset) @@ -41,7 +41,7 @@ class Alignment(object): ''' Assuming the given external_align, checks whether self is fulfilled for all cases. - Returns True if yes, False otherwise. + Returns True if yes, False otherwise. ''' if self.align == 1 and self.offset == 0: # alignment 1 with offset 0 is always fulfilled @@ -55,9 +55,9 @@ class Alignment(object): # the external align guarantees less alignment -> not guaranteed return False - if external_align.align % self.align != 0: + if external_align.align % self.align != 0: # the external align cannot be divided by our align - # -> not guaranteed + # -> not guaranteed # (this can only happen if there are alignments that are not # a power of 2, which is highly discouraged. But better be # safe and check for it) @@ -72,7 +72,7 @@ class Alignment(object): def combine_with(self, other): # returns the alignment that is guaranteed when - # both, self or other, can happen + # both, self or other, can happen new_align = gcd(self.align, other.align) new_offset_candidate1 = self.offset % new_align new_offset_candidate2 = other.offset % new_align @@ -83,8 +83,8 @@ class Alignment(object): new_align = gcd(new_align, offset_diff) new_offset_candidate1 = self.offset % new_align new_offset_candidate2 = other.offset % new_align - assert new_offset_candidate1 == new_offset_candidate2 - new_offset = new_offset_candidate1 + assert new_offset_candidate1 == new_offset_candidate2 + new_offset = new_offset_candidate1 # return the result return Alignment(new_align, new_offset) @@ -92,44 +92,44 @@ class Alignment(object): class AlignmentLog(object): def __init__(self): - self.ok_list = [] - self.fail_list = [] - self.verbosity = 1 + self.ok_list = [] + self.fail_list = [] + self.verbosity = 1 def __str__(self): - result = "" + result = "" - # output the OK-list - for (align_before, field_name, type_obj, callstack, align_after) in self.ok_list: - stacksize = len(callstack) + # output the OK-list + for (align_before, field_name, type_obj, callstack, align_after) in self.ok_list: + stacksize = len(callstack) indent = ' ' * stacksize - if self.ok_callstack_is_relevant(callstack): + if self.ok_callstack_is_relevant(callstack): if field_name is None or field_name == "": - result += (" %sok: %s:\n\t%sbefore: %s, after: %s\n" - % (indent, str(type_obj), indent, str(align_before), str(align_after))) - else: - result += (" %sok: field \"%s\" in %s:\n\t%sbefore: %s, after: %s\n" - % (indent, str(field_name), str(type_obj), - indent, str(align_before), str(align_after))) + result += (" %sok: %s:\n\t%sbefore: %s, after: %s\n" + % (indent, str(type_obj), indent, str(align_before), str(align_after))) + else: + result += (" %sok: field \"%s\" in %s:\n\t%sbefore: %s, after: %s\n" + % (indent, str(field_name), str(type_obj), + indent, str(align_before), str(align_after))) if self.verbosity >= 1: - result += self.callstack_to_str(indent, callstack) + result += self.callstack_to_str(indent, callstack) - # output the fail-list - for (align_before, field_name, type_obj, callstack, reason) in self.fail_list: - stacksize = len(callstack) + # output the fail-list + for (align_before, field_name, type_obj, callstack, reason) in self.fail_list: + stacksize = len(callstack) indent = ' ' * stacksize - if field_name is None or field_name == "": - result += (" %sfail: align %s is incompatible with\n\t%s%s\n\t%sReason: %s\n" - % (indent, str(align_before), indent, str(type_obj), indent, reason)) - else: - result += (" %sfail: align %s is incompatible with\n\t%sfield \"%s\" in %s\n\t%sReason: %s\n" - % (indent, str(align_before), indent, str(field_name), str(type_obj), indent, reason)) + if field_name is None or field_name == "": + result += (" %sfail: align %s is incompatible with\n\t%s%s\n\t%sReason: %s\n" + % (indent, str(align_before), indent, str(type_obj), indent, reason)) + else: + result += (" %sfail: align %s is incompatible with\n\t%sfield \"%s\" in %s\n\t%sReason: %s\n" + % (indent, str(align_before), indent, str(field_name), str(type_obj), indent, reason)) if self.verbosity >= 1: - result += self.callstack_to_str(indent, callstack) + result += self.callstack_to_str(indent, callstack) - return result + return result def callstack_to_str(self, indent, callstack): @@ -137,41 +137,41 @@ class AlignmentLog(object): for stack_elem in callstack: result += "\t %s%s\n" % (indent, str(stack_elem)) result += "\t%s]\n" % indent - return result + return result def ok_callstack_is_relevant(self, ok_callstack): # determine whether an ok callstack is relevant for logging - if self.verbosity >= 2: - return True - - # empty callstacks are always relevant - if len(ok_callstack) == 0: + if self.verbosity >= 2: return True - # check whether the ok_callstack is a subset or equal to a fail_callstack + # empty callstacks are always relevant + if len(ok_callstack) == 0: + return True + + # check whether the ok_callstack is a subset or equal to a fail_callstack for (align_before, field_name, type_obj, fail_callstack, reason) in self.fail_list: if len(ok_callstack) <= len(fail_callstack): zipped = zip(ok_callstack, fail_callstack[:len(ok_callstack)]) - is_subset = all([i == j for i, j in zipped]) - if is_subset: + is_subset = all([i == j for i, j in zipped]) + if is_subset: return True return False def ok(self, align_before, field_name, type_obj, callstack, align_after): - self.ok_list.append((align_before, field_name, type_obj, callstack, align_after)) + self.ok_list.append((align_before, field_name, type_obj, callstack, align_after)) def fail(self, align_before, field_name, type_obj, callstack, reason): - self.fail_list.append((align_before, field_name, type_obj, callstack, reason)) + self.fail_list.append((align_before, field_name, type_obj, callstack, reason)) def append(self, other): - self.ok_list.extend(other.ok_list) - self.fail_list.extend(other.fail_list) + self.ok_list.extend(other.ok_list) + self.fail_list.extend(other.fail_list) def ok_count(self): - return len(self.ok_list) + return len(self.ok_list) diff --git a/proto/xcb-proto/xcbgen/expr.py b/proto/xcb-proto/xcbgen/expr.py index a716d3443..bf46c6360 100644 --- a/proto/xcb-proto/xcbgen/expr.py +++ b/proto/xcb-proto/xcbgen/expr.py @@ -169,6 +169,7 @@ class Expression(object): else: self.lenfield_parent = p self.lenfield_type = fields[self.lenfield_name].field_type + self.lenfield = fields[self.lenfield_name] break self.recursive_resolve_tasks(module, parents) diff --git a/proto/xcb-proto/xcbgen/matcher.py b/proto/xcb-proto/xcbgen/matcher.py index bfa315eb5..97a8b43bb 100644 --- a/proto/xcb-proto/xcbgen/matcher.py +++ b/proto/xcb-proto/xcbgen/matcher.py @@ -57,6 +57,12 @@ def struct(node, module, namespace): type = Struct(name, node) module.add_type(id, namespace.ns, name, type) +def eventstruct(node, module, namespace): + id = node.get('name') + name = namespace.prefix + (id,) + type = EventStruct(name, node) + module.add_type(id, namespace.ns, name, type) + def union(node, module, namespace): id = node.get('name') name = namespace.prefix + (id,) @@ -103,6 +109,7 @@ funcs = {'import' : import_, 'xidunion' : xidunion, 'enum' : enum, 'struct' : struct, + 'eventstruct' : eventstruct, 'union' : union, 'request' : request, 'event' : event, diff --git a/proto/xcb-proto/xcbgen/state.py b/proto/xcb-proto/xcbgen/state.py index a6ad3a11e..a8346bb20 100644 --- a/proto/xcb-proto/xcbgen/state.py +++ b/proto/xcb-proto/xcbgen/state.py @@ -32,6 +32,9 @@ class Namespace(object): self.root = parse(filename).getroot() self.header = self.root.get('header') self.ns = self.header + ':' + + # Events + self.events = {} # Get root element attributes if self.root.get('extension-xname', False): @@ -46,6 +49,17 @@ class Namespace(object): self.ext_name = '' self.prefix = ('xcb',) + def add_event(self, id, name, item): + self.events[id] = (name, item) + + def get_event_by_opcode(self, opcode, is_ge_event): + for id, (name, event) in self.events.items(): + if event.is_ge_event == is_ge_event: + opcode_specific_name = event.get_name_for_opcode( opcode ) + if opcode_specific_name is not None: + return (opcode_specific_name, event) + return None + class Module(object): ''' @@ -72,6 +86,11 @@ class Module(object): self.errors = {} self.all = [] + # dict of namespaces by ext_name + self.namespaces = {} + # enter the main namespace here + self.namespaces[self.namespace.ext_name] = self.namespace + # Register some common types self.add_type('CARD8', '', ('uint8_t',), tcard8) self.add_type('CARD16', '', ('uint16_t',), tcard16) @@ -94,6 +113,7 @@ class Module(object): # Recursively resolve all types def resolve(self): + self.add_events_to_namespaces() for (name, item) in self.all: self.pads = 0 item.resolve(self) @@ -112,6 +132,7 @@ class Module(object): if self.import_level == 0: self.direct_imports.append((name, namespace.header)) self.imports.append((name, namespace.header)) + self.namespaces[namespace.ext_name] = namespace def has_import(self, name): for (name_, header) in self.imports: @@ -149,6 +170,9 @@ class Module(object): def get_type_name(self, id): return self.get_type_impl(id, 0) + def get_namespace(self, ext_name): + return self.namespaces[ext_name] + # Keeps track of request datatypes def add_request(self, id, name, item): if name[:-1] == self.namespace.prefix: @@ -160,6 +184,23 @@ class Module(object): if name[:-1] == self.namespace.prefix: self.all.append((name, item)) + + def add_events_to_namespaces(self): + # add to its namespace object + for id, (name,item) in self.events.items(): + if name[:-1] == ('xcb',): + # core event + namespace_name = '' + else: + # extension event + namespace_name = name[-2] + + namespace = self.namespaces[namespace_name] + + if namespace is not None: + namespace.add_event(id, name, item) + + def get_event(self, id): return self.events[id][1] diff --git a/proto/xcb-proto/xcbgen/xtypes.py b/proto/xcb-proto/xcbgen/xtypes.py index c3b57583d..1e270ae61 100644 --- a/proto/xcb-proto/xcbgen/xtypes.py +++ b/proto/xcb-proto/xcbgen/xtypes.py @@ -36,10 +36,13 @@ class Type(object): self.is_reply = False self.is_union = False self.is_pad = False + self.is_eventstruct = False + self.is_event = False self.is_switch = False self.is_case_or_bitcase = False self.is_bitcase = False self.is_case = False + self.is_fd = False self.required_start_align = Alignment() # the biggest align value of an align-pad contained in this type @@ -66,7 +69,7 @@ class Type(object): ''' raise Exception('abstract fixed_size method not overridden!') - def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum=None): + def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum=None, is_fd=False): ''' Default method for making a data type a member of a structure. Extend this if the data type needs to add an additional length field or something. @@ -75,7 +78,7 @@ class Type(object): complex_type is the structure object. see Field for the meaning of the other parameters. ''' - new_field = Field(self, field_type, field_name, visible, wire, auto, enum) + new_field = Field(self, field_type, field_name, visible, wire, auto, enum, is_fd) # We dump the _placeholder_byte if any fields are added. for (idx, field) in enumerate(complex_type.fields): @@ -215,6 +218,18 @@ tchar = SimpleType(('char',), 1) tfloat = SimpleType(('float',), 4) tdouble = SimpleType(('double',), 8) +class FileDescriptor(SimpleType): + ''' + Derived class which represents a file descriptor. + ''' + def __init__(self): + SimpleType.__init__(self, ('int'), 4) + self.is_fd = True + + def fixed_size(self): + return True + + out = __main__.output['simple'] class Enum(SimpleType): ''' @@ -308,7 +323,9 @@ class ListType(Type): type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False, enum) # Add ourself to the structure by calling our original method. - Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum) + if self.member.is_fd: + wire = False + Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum, self.member.is_fd) def resolve(self, module): if self.resolved: @@ -501,7 +518,7 @@ class ComplexType(Type): int(required_start_align_element.get('align', "4"), 0), int(required_start_align_element.get('offset', "0"), 0)) if verbose_align_log: - print "Explicit start-align for %s: %s\n" % (self, self.required_start_align) + print ("Explicit start-align for %s: %s\n" % (self, self.required_start_align)) def resolve(self, module): if self.resolved: @@ -530,7 +547,12 @@ class ComplexType(Type): elif child.tag == 'list': field_name = child.get('name') fkey = child.get('type') - type = ListType(child, module.get_type(fkey), *self.lenfield_parent) + if fkey == 'fd': + ftype = FileDescriptor() + fkey = 'INT32' + else: + ftype = module.get_type(fkey) + type = ListType(child, ftype, *self.lenfield_parent) visible = True elif child.tag == 'switch': field_name = child.get('name') @@ -592,7 +614,7 @@ class ComplexType(Type): if verbose_align_log: print ("calc_required_start_align: %s has start-align %s" % (str(self), str(self.required_start_align))) - print "Details:\n" + str(log) + print ("Details:\n" + str(log)) if self.required_start_align.offset != 0: print (("WARNING: %s\n\thas start-align with non-zero offset: %s" + "\n\tsuggest to add explicit definition with:" @@ -619,12 +641,12 @@ class ComplexType(Type): for offset in range(0,align): align_candidate = Alignment(align, offset) if verbose_align_log: - print "trying %s for %s" % (str(align_candidate), str(self)) + print ("trying %s for %s" % (str(align_candidate), str(self))) my_log = AlignmentLog() if self.is_possible_start_align(align_candidate, callstack, my_log): log.append(my_log) if verbose_align_log: - print "found start-align %s for %s" % (str(align_candidate), str(self)) + print ("found start-align %s for %s" % (str(align_candidate), str(self))) return align_candidate else: my_ok_count = my_log.ok_count() @@ -641,7 +663,7 @@ class ComplexType(Type): # none of the candidates applies # this type has illegal internal aligns for all possible start_aligns if verbose_align_log: - print "didn't find start-align for %s" % str(self) + print ("didn't find start-align for %s" % str(self)) log.append(best_log) return None @@ -900,7 +922,7 @@ class SwitchType(ComplexType): # aux function for unchecked_get_alignment_after def get_align_for_selected_case_field(self, case_field, start_align, callstack, log): if verbose_align_log: - print "get_align_for_selected_case_field: %s, case_field = %s" % (str(self), str(case_field)) + print ("get_align_for_selected_case_field: %s, case_field = %s" % (str(self), str(case_field))) total_align = start_align for field in self.bitcases: my_callstack = callstack[:] @@ -1164,6 +1186,82 @@ class Request(ComplexType): out = __main__.output['request'] +class EventStructAllowedRule: + + def __init__(self, parent, elt): + self.elt = elt + self.extension = elt.get('extension') + self.ge_events = elt.get('xge') == "true" + self.min_opcode = int( elt.get('opcode-min') ) + self.max_opcode = int( elt.get('opcode-max') ) + + def resolve(self, parent, module): + # get the namespace of the specified extension + extension_namespace = module.get_namespace( self.extension ) + if extension_namespace is None: + raise Exception( "EventStructAllowedRule.resolve: cannot find extension \"" + self.extension + "\"" ) + return + + # find and add the selected events + for opcode in range(self.min_opcode, self.max_opcode): + name_and_event = extension_namespace.get_event_by_opcode( opcode, self.ge_events ) + if name_and_event is None: + # could not find event -> error handling + if self.ge_events: + raise Exception("EventStructAllowedRule.resolve: cannot find xge-event with opcode " + str(opcode) + " in extension " + self.extension ) + else: + raise Exception("EventStructAllowedRule.resolve: cannot find oldstyle-event with opcode " + str(opcode) + " in extension " + self.extension ) + return + + ( name, event ) = name_and_event + # add event to EventStruct + parent.add_event( module, self.extension, opcode, name, event ) + + +class EventStruct(Union): + ''' + Derived class representing an event-use-as-struct data type. + ''' + + def __init__(self, name, elt): + Union.__init__(self, name, elt) + self.is_eventstruct = True + self.events = [] + self.allowedRules = [] + self.contains_ge_events = False + for item in list(elt): + if item.tag == 'allowed': + allowedRule = EventStructAllowedRule(self, item) + self.allowedRules.append( allowedRule ) + if allowedRule.ge_events: + self.contains_ge_events = True + + out = __main__.output['eventstruct'] + + def resolve(self, module): + if self.resolved: + return + for allowedRule in self.allowedRules: + allowedRule.resolve(self, module) + Union.resolve(self,module) + self.resolved = True + + # add event. called by resolve + def add_event(self, module, extension, opcode, name, event_type ): + self.events.append( (extension, opcode, name, event_type) ) + # Add the field to ourself + event_type.make_member_of(module, self, name, name[-1], True, True, False) + # Recursively resolve the event (could be another structure, list) + event_type.resolve(module) + + def fixed_size(self): + is_fixed_size = True + for extension, opcode, name, event in self.events: + if not event.fixed_size(): + is_fixed_size = False + return is_fixed_size + + class Event(ComplexType): ''' Derived class representing an event data type. @@ -1183,6 +1281,8 @@ class Event(ComplexType): self.is_ge_event = bool(elt.get('xge')) + self.is_event = True + self.doc = None for item in list(elt): if item.tag == 'doc': @@ -1193,6 +1293,13 @@ class Event(ComplexType): if main: self.name = name + def get_name_for_opcode(self, opcode): + for name, my_opcode in self.opcodes.items(): + if int(my_opcode) == opcode: + return name + else: + return None + def resolve(self, module): def add_event_header(): self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))