1# Copyright (C) 2021-2022 Intel Corporation.
2#
3# SPDX-License-Identifier: BSD-3-Clause
4#
5
6import lxml, re
7from pathlib import Path
8
9def add_child(element, tag, text=None, **kwargs):
10    child = lxml.etree.Element(tag)
11    child.text = text
12    for k,v in kwargs.items():
13        child.set(k, v)
14    element.append(child)
15    return child
16
17def get_node(etree, xpath):
18    result = etree.xpath(xpath)
19    assert len(result) <= 1, \
20        "Internal error: cannot get texts from multiple nodes at a time.  " \
21        "Rerun the Board Inspector with `--loglevel debug`.  If this issue persists, " \
22        "log a new issue at https://github.com/projectacrn/acrn-hypervisor/issues and attach the full logs."
23    return result[0] if len(result) == 1 else None
24
25def get_realpath(pathstr):
26    assert isinstance(pathstr, str), f"Internal error: pathstr must be a str: {type(pathstr)}"
27    path = Path(pathstr)
28    assert path.exists(), f"Internal error: {path} does not exist"
29    return str(path.resolve())
30
31def get_bdf_from_realpath(pathstr):
32    realpath = get_realpath(pathstr)
33    bdf_regex = re.compile(r"^([0-9a-f]{4}):([0-9a-f]{2}):([0-9a-f]{2}).([0-7]{1})$")
34    m = bdf_regex.match(realpath.split('/')[-1])
35    assert m, f"Internal error: {realpath} contains no matched pattern: {bdf_regex}"
36    return int(m.group(2), base=16), int(m.group(3), base=16), int(m.group(4), base=16)
37