Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple cluster codes for enums in xmls #26476

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 60 additions & 7 deletions scripts/py_matter_idl/matter_idl/test_xml_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,19 @@
from typing import List, Union

try:
from matter_idl.matter_idl_types import (AccessPrivilege, Attribute, AttributeQuality, Bitmap, Cluster, ClusterSide, Command,
ConstantEntry, DataType, Event, EventPriority, EventQuality, Field, FieldQuality, Idl,
Struct, StructQuality, StructTag)
from matter_idl.zapxml import ParseSource, ParseXmls
except ImportError:
import os
import sys

sys.path.append(os.path.abspath(
os.path.join(os.path.dirname(__file__), '..')))

from matter_idl.matter_idl_types import (AccessPrivilege, Attribute, AttributeQuality, Bitmap, Cluster, ClusterSide, Command,
ConstantEntry, DataType, Event, EventPriority, EventQuality, Field, FieldQuality, Idl,
Struct, StructQuality, StructTag)
from matter_idl.zapxml import ParseSource, ParseXmls

from matter_idl.matter_idl_types import (AccessPrivilege, Attribute, AttributeQuality, Bitmap, Cluster, ClusterSide, Command,
ConstantEntry, DataType, Enum, Event, EventPriority, EventQuality, Field, FieldQuality,
Idl, Struct, StructQuality, StructTag)


def XmlToIdl(what: Union[str, List[str]]) -> Idl:
if not isinstance(what, list):
Expand Down Expand Up @@ -223,6 +220,62 @@ def testFabricScopedAndSensitive(self):
qualities=StructQuality.FABRIC_SCOPED)],
)]))

def testEnum(self):
idl = XmlToIdl('''<?xml version="1.0"?>
<configurator>
<cluster><name>Test1</name><code>10</code></cluster>
<cluster><name>Test2</name><code>20</code></cluster>
andy31415 marked this conversation as resolved.
Show resolved Hide resolved

<enum name="GlobalEnum" type="ENUM8">
<item value="0" name="First" />
<item value="1" name="Second" />
</enum>

<enum name="OneCluster" type="ENUM8">
<cluster code="10" />
<item value="3" name="Three" />
</enum>

<enum name="TwoClusters" type="ENUM8">
<cluster code="10" />
<cluster code="20" />
<item value="100" name="Big" />
<item value="2000" name="Bigger" />
</enum>
</configurator>
''')
e1 = Enum(
name='GlobalEnum',
base_type="ENUM8",
entries=[
ConstantEntry(name="First", code=0),
ConstantEntry(name="Second", code=1),
]
)
e2 = Enum(
name='OneCluster',
base_type="ENUM8",
entries=[
ConstantEntry(name="Three", code=3),
]
)
e3 = Enum(
name='TwoClusters',
base_type="ENUM8",
entries=[
ConstantEntry(name="Big", code=100),
ConstantEntry(name="Bigger", code=2000),
]
)
self.assertEqual(idl,
Idl(clusters=[
Cluster(side=ClusterSide.CLIENT,
name='Test1', code=10, enums=[e2, e3]),
Cluster(side=ClusterSide.CLIENT,
name='Test2', code=20, enums=[e3])],
enums=[e1],
))

def testStruct(self):
idl = XmlToIdl('''<?xml version="1.0"?>
<configurator>
Expand Down
24 changes: 12 additions & 12 deletions scripts/py_matter_idl/matter_idl/zapxml/handlers/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,10 @@ class EnumHandler(BaseHandler, IdlPostProcessor):

def __init__(self, context: Context, attrs):
super().__init__(context)
self._cluster_code = None # if set, enum belongs to a specific cluster

# no cluster codes means global. Note that at the time
# of writing this, no global enums were defined in XMLs
self._cluster_codes = set()
self._enum = Enum(name=attrs['name'],
base_type=attrs['type'], entries=[])

Expand All @@ -260,10 +263,7 @@ def GetNextProcessor(self, name, attrs):
))
return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG)
elif name.lower() == 'cluster':
if self._cluster_code is not None:
raise Exception(
'Multiple cluster codes for enum %s' % self._enum.name)
self._cluster_code = ParseInt(attrs['code'])
self._cluster_codes.add(ParseInt(attrs['code']))
return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG)
else:
return BaseHandler(self.context)
Expand All @@ -273,18 +273,18 @@ def FinalizeProcessing(self, idl: Idl):
# - inside a cluster if a code exists
# - inside top level if a code does not exist

if self._cluster_code is None:
if not self._cluster_codes:
idl.enums.append(self._enum)
else:
found = False
found = set()
for c in idl.clusters:
if c.code == self._cluster_code:
if c.code in self._cluster_codes:
c.enums.append(self._enum)
found = True
found.add(c.code)

if not found:
LOGGER.error('Enum %s could not find its cluster (code %d/0x%X)' %
(self._enum.name, self._cluster_code, self._cluster_code))
if found != self._cluster_codes:
LOGGER.error('Enum %s could not find its clusters (codes: %r)' %
(self._enum.name, self._cluster_codes - found))

def EndProcessing(self):
self.context.AddIdlPostProcessor(self)
Expand Down