summaryrefslogtreecommitdiffstats
path: root/meta/lib/oe/whence.py
blob: 3e0b53319d531ab71f117988b85d34c12918d6a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#! /usr/bin/env python3

import sys
import re
import dataclasses

@dataclasses.dataclass()
class Driver:
    name: str
    description: str
    files: list[str] = dataclasses.field(default_factory=list)
    licence_name: str = None
    licence_file: str = None

def prime(fn):
    def wrapper(*args, **kwargs):
        v = fn(*args, **kwargs)
        v.send(None)
        return v
    return wrapper

class Parser:
    def __init__(self):
        self.state_new_device = self.parse_new_device()
        self.state_files = self.parse_files()
        self.state_licence = self.parse_licence()
        self.state = self.state_new_device

        self.driver = None
        self.drivers = {}

    def send(self, line):
        try:
            self.state.send(line)
        except StopIteration:
            self.stopped = True

    @prime
    def parse_new_device(self):
        while True:
            line = yield
            m = re.match(r"Driver: *(?P<name>\S*)[ -]*(?P<description>.+)?", line)
            if m:
                name, description = m.groups()
                try:
                    self.driver = self.drivers[name]
                except KeyError:
                    self.driver = Driver(name, description)
                    self.drivers[name] = self.driver
                self.state = self.state_files

    @prime
    def parse_files(self):
        while True:
            line = yield
            if line.startswith("------"):
                self.state = self.state_new_device
                continue

            m = re.match(r"(?:RawFile|File):\s*(.+)", line)
            if m:
                # TODO: also need to handle escapes?
                self.driver.files.append(m.group(1).strip('"'))
                continue

            m = re.match(r"Link:\s*(.+)", line)
            if m:
                linkname, target = m.group(1).split("->")
                linkname = linkname.strip().replace(r"\ ", " ")
                self.driver.files.append(linkname)
                continue

            m = re.match(r"Licen[cs]e:", line)
            if m:
                self.state = self.state_licence
                self.state.send(line)
                continue

    @prime
    def parse_licence(self):
        while True:
            line = yield
            if line.startswith("------"):
                self.state = self.state_new_device
                continue

            m = re.match(r"Licen[cs]e: *Redistributable.*(LICEN[CS]E\.(\S+?)(?:\.txt)?) for details", line)
            if m:
                self.driver.licence_name = m.group(2)
                self.driver.licence_file = m.group(1)
                self.state = self.state_files
                continue

            # TODO handle inline


    def parse(self, filename):
        with open(filename) as f:
            for line in f:
                self.send(line.strip())
    
        return self.drivers.values()

if __name__ == "__main__":
    parser = Parser()

    drivers = parser.parse(sys.argv[1])

    print(f"Parsed {len(drivers)} drivers")
    for d in drivers:
        print(f"{d.name} ({d.description})")
        print(d.files)
        print(d.licence_file)