Skip to content

Commit

Permalink
Merge pull request sifive#34 from sifive/fix-handles-in-path
Browse files Browse the repository at this point in the history
Allow paths to include multiple nodes with unit addresses
  • Loading branch information
nategraff-sifive authored Dec 3, 2019
2 parents 0b1b91d + f760a5c commit 83db23c
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 19 deletions.
17 changes: 5 additions & 12 deletions pydevicetree/ast/reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,13 @@ def to_dts(self) -> str:

class Path:
"""A Path uniquely identifies a Node by its parents and (optionally) unit address"""
def __init__(self, path: str, address: Optional[int] = None):
def __init__(self, path: str):
"""Create a path out of a string"""
self.path = list(filter(lambda s: s != '', path.split('/')))
self.address = address
self.path = path

def to_dts(self) -> str:
"""Format the Path in Devicetree Source format"""
if self.address:
return '/%s@%x' % ('/'.join(self.path), self.address)
return '/' + '/'.join(self.path)
return self.path

def __repr__(self) -> str:
return "<Path " + self.to_dts() + ">"
Expand All @@ -51,19 +48,15 @@ def __eq__(self, other: object) -> bool:
if isinstance(other, Path):
return self.to_dts() == other.to_dts()
if isinstance(other, str):
if ("@" not in other) and (self.address is not None):
return self.to_dts().split("@")[0] == other
return self.to_dts() == other
return False

def __iter__(self) -> Iterator[str]:
return iter(['/'] + self.path)
return iter(self.path.split("/"))

def replace(self, old: str, new: str) -> 'Path':
"""Replace any elements of the path which match 'old' with a new element 'new'"""
path = [e.replace(old, new) for e in self.path]
return Path('/' + '/'.join(path), self.address)

return Path(self.path.replace(old, new))

class Reference:
"""A Reference is a Devicetree construct which points to a Node in the tree
Expand Down
7 changes: 3 additions & 4 deletions pydevicetree/source/grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
node_name = p.Word(p.alphanums + ",.-+_") ^ p.Literal("/")
integer = p.pyparsing_common.integer ^ (p.Literal("0x").suppress() + p.pyparsing_common.hex_integer)
unit_address = p.pyparsing_common.hex_integer
node_handle = node_name("node_name") + p.Optional(p.Literal("@") + unit_address("address"))
property_name = p.Word(p.alphanums + ",.-_+?#")
label = p.Word(p.alphanums + "_").setResultsName("label")
label_creation = p.Combine(label + p.Literal(":"))
string = p.QuotedString(quoteChar='"')
stringlist = p.delimitedList(string)
node_path = p.Combine(p.Literal("/") + \
p.delimitedList(node_name, delim="/", combine=True)).setResultsName("path") + \
p.Optional(p.Literal("@").suppress() + unit_address("address"))
p.delimitedList(node_handle, delim="/", combine=True)).setResultsName("path")
path_reference = p.Literal("&{").suppress() + node_path + p.Literal("}").suppress()
label_reference = p.Literal("&").suppress() + label
reference = path_reference ^ label_reference
Expand All @@ -43,8 +43,7 @@
property_assignment = property_name("property_name") + p.Optional(p.Literal("=").suppress() + \
(property_values)).setResultsName("value") + p.Literal(";").suppress()

node_opener = p.Optional(label_creation) + node_name("node_name") + \
p.Optional(p.Literal("@").suppress() + unit_address("address")) + p.Literal("{").suppress()
node_opener = p.Optional(label_creation) + node_handle + p.Literal("{").suppress()
node_reference_opener = reference + p.Literal("{").suppress()
node_closer = p.Literal("}").suppress() + p.Literal(";").suppress()
node_definition = p.Forward()
Expand Down
11 changes: 8 additions & 3 deletions pydevicetree/source/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,14 @@ def transformLabel(string, location, tokens):

def transformPath(string, location, tokens):
"""Transforms a ParseResult into a Path"""
if tokens.address:
return Path(tokens.path, tokens.address)
return Path(tokens.path)
path = ""
for handle in tokens.path[0].split("/"):
if "@" in handle:
node, address = handle.split("@")
path += "/%s@%x" % (node, int(address))
elif handle != "":
path += "/" + handle
return Path(path)

def transformPathReference(string, location, tokens):
"""Transforms a ParseResult into a PathReference"""
Expand Down
2 changes: 2 additions & 0 deletions tests/test_grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ def test_label(self):
def test_node_path(self):
from pydevicetree.ast import Path
self.assertEqual(node_path.parseString("/path/to/foo@deadbeef")[0], Path("/path/to/foo@deadbeef"))
self.assertEqual(node_path.parseString("/path/to@0/foo@deadbeef")[0], Path("/path/to@0/foo@deadbeef"))

def test_reference(self):
from pydevicetree.ast import Label, Path
self.assertEqual(reference.parseString("&mylabel")[0].label, Label("mylabel"))
self.assertEqual(reference.parseString("&{/path/to/foo@deadbeef}")[0].path, Path("/path/to/foo@deadbeef"))
self.assertEqual(reference.parseString("&{/path/to@0/foo@deadbeef}")[0].path, Path("/path/to@0/foo@deadbeef"))

def test_arith_expr(self):
self.assertEqual(arith_expr.parseString("(1 + 2)").asList(), [3])
Expand Down

0 comments on commit 83db23c

Please sign in to comment.