Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 355e79f1 authored by Yu Shan's avatar Yu Shan Committed by Gerrit Code Review
Browse files

Merge "Fix AIDL VHAL metadata extraction script" into main

parents 42876b80 1e14bd55
Loading
Loading
Loading
Loading
+3063 −1920

File changed.

Preview size limit exceeded, changes collapsed.

+70 −31
Original line number Original line Diff line number Diff line
@@ -19,23 +19,56 @@ import sys


from pathlib import Path
from pathlib import Path


RE_PACKAGE = re.compile(r"\npackage\s([\.a-z0-9]*);")
RE_IMPORT = re.compile(r"\nimport\s([\.a-zA-Z0-9]*);")
RE_ENUM = re.compile(r"\s*enum\s+(\w*) {\n(.*)}", re.MULTILINE | re.DOTALL)
RE_ENUM = re.compile(r"\s*enum\s+(\w*) {\n(.*)}", re.MULTILINE | re.DOTALL)
RE_COMMENT = re.compile(r"(?:(?:\/\*\*)((?:.|\n)*?)(?:\*\/))?(?:\n|^)\s*(\w*)(?:\s+=\s*)?((?:[a-zA-Z0-9]|\s|\+|)*),", re.DOTALL)
RE_COMMENT = re.compile(r"(?:(?:\/\*\*)((?:.|\n)*?)(?:\*\/))?(?:\n|^)\s*(\w*)(?:\s+=\s*)?((?:[\.\-a-zA-Z0-9]|\s|\+|)*),",
                        re.DOTALL)
RE_BLOCK_COMMENT_TITLE = re.compile("^(?:\s|\*)*((?:\w|\s|\.)*)\n(?:\s|\*)*(?:\n|$)")
RE_BLOCK_COMMENT_TITLE = re.compile("^(?:\s|\*)*((?:\w|\s|\.)*)\n(?:\s|\*)*(?:\n|$)")
RE_BLOCK_COMMENT_ANNOTATION = re.compile("^(?:\s|\*)*@(\w*)\s+((?:\w|:)*)", re.MULTILINE)
RE_BLOCK_COMMENT_ANNOTATION = re.compile("^(?:\s|\*)*@(\w*)\s+((?:[\w:\.])*)", re.MULTILINE)
RE_HEX_NUMBER = re.compile("([0-9A-Fa-fxX]+)")
RE_HEX_NUMBER = re.compile("([\.\-0-9A-Za-z]+)")




class JEnum:
class JEnum:
    def __init__(self, name):
    def __init__(self, package, name):
        self.package = package
        self.name = name
        self.name = name
        self.values = []
        self.values = []


class Enum:
    def __init__(self, package, name, text, imports):
        self.text = text
        self.parsed = False
        self.imports = imports
        self.jenum = JEnum(package, name)


class Converter:
    def parse(self, enums):
    # Only addition is supported for now, but that covers all existing properties except
        if self.parsed:
    # OBD diagnostics, which use bitwise shifts
            return
    def calculateValue(self, expression, default_value):
        for dep in self.imports:
            enums[dep].parse(enums)
        print("Parsing " + self.jenum.name)
        matches = RE_COMMENT.findall(self.text)
        defaultValue = 0
        for match in matches:
            value = dict()
            value['name'] = match[1]
            value['value'] = self.calculateValue(match[2], defaultValue, enums)
            defaultValue = value['value'] + 1
            if self.jenum.name == "VehicleProperty":
                block_comment = match[0]
                self.parseBlockComment(value, block_comment)
            self.jenum.values.append(value)
        self.parsed = True
        self.text = None

    def get_value(self, value_name):
        for value in self.jenum.values:
            if value['name'] == value_name:
                return value['value']
        raise Exception("Cannot decode value: " + self.jenum.package + " : " + value_name)

    def calculateValue(self, expression, default_value, enums):
        numbers = RE_HEX_NUMBER.findall(expression)
        numbers = RE_HEX_NUMBER.findall(expression)
        if len(numbers) == 0:
        if len(numbers) == 0:
            return default_value
            return default_value
@@ -44,6 +77,12 @@ class Converter:
        if numbers[0].lower().startswith("0x"):
        if numbers[0].lower().startswith("0x"):
            base = 16
            base = 16
        for number in numbers:
        for number in numbers:
            if '.' in number:
                package, val_name = number.split('.')
                for dep in self.imports:
                    if package in dep:
                        result += enums[dep].get_value(val_name)
            else:
                result += int(number, base)
                result += int(number, base)
        return result
        return result


@@ -54,30 +93,22 @@ class Converter:
            break
            break
        annots_res = RE_BLOCK_COMMENT_ANNOTATION.findall(blockComment)
        annots_res = RE_BLOCK_COMMENT_ANNOTATION.findall(blockComment)
        for annot in annots_res:
        for annot in annots_res:
            value[annot[0]] = annot[1]
            value[annot[0]] = annot[1].replace(".", ":")

    def parseEnumContents(self, enum: JEnum, enumValue):
        matches = RE_COMMENT.findall(enumValue)
        defaultValue = 0
        for match in matches:
            value = dict()
            value['name'] = match[1]
            value['value'] = self.calculateValue(match[2], defaultValue)
            defaultValue = value['value'] + 1
            if enum.name == "VehicleProperty":
                block_comment = match[0]
                self.parseBlockComment(value, block_comment)
            enum.values.append(value)


class Converter:
    # Only addition is supported for now, but that covers all existing properties except
    # OBD diagnostics, which use bitwise shifts
    def convert(self, input):
    def convert(self, input):
        text = Path(input).read_text()
        text = Path(input).read_text()
        matches = RE_ENUM.findall(text)
        matches = RE_ENUM.findall(text)
        jenums = []
        package = RE_PACKAGE.findall(text)[0]
        imports = RE_IMPORT.findall(text)
        enums = []
        for match in matches:
        for match in matches:
            enum = JEnum(match[0])
            enum = Enum(package, match[0], match[1], imports)
            self.parseEnumContents(enum, match[1])
            enums.append(enum)
            jenums.append(enum)
        return enums
        return jenums



def main():
def main():
    if (len(sys.argv) != 3):
    if (len(sys.argv) != 3):
@@ -85,10 +116,18 @@ def main():
        sys.exit(1)
        sys.exit(1)
    aidl_path = sys.argv[1]
    aidl_path = sys.argv[1]
    out_path = sys.argv[2]
    out_path = sys.argv[2]
    result = []
    enums_dict = dict()
    for file in os.listdir(aidl_path):
    for file in os.listdir(aidl_path):
        result.extend(Converter().convert(os.path.join(aidl_path, file)))
        enums = Converter().convert(os.path.join(aidl_path, file))
    json_result = json.dumps(result, default=vars, indent=2)
        for enum in enums:
            enums_dict[enum.jenum.package + "." + enum.jenum.name] = enum

    result = []
    for enum_name, enum in enums_dict.items():
        enum.parse(enums_dict)
        result.append(enum.jenum.__dict__)

    json_result = json.dumps(result, default=None, indent=2)
    with open(out_path, 'w') as f:
    with open(out_path, 'w') as f:
        f.write(json_result)
        f.write(json_result)