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
|
// Copyright 2023 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
package subsystem
type Subsystem struct {
Name string
PathRules []PathRule
Syscalls []string
Lists []string
Maintainers []string
Parents []*Subsystem
// If NoReminders is true, there should be no monthly reports for the subsystem.
NoReminders bool
// If NoIndirectCc is true, the subsystem lists are not tagged in sub-subsystem reports.
NoIndirectCc bool
}
// ReachableParents returns the set of subsystems reachable from the current one.
func (subsystem *Subsystem) ReachableParents() map[*Subsystem]struct{} {
ret := make(map[*Subsystem]struct{})
var dfs func(node *Subsystem)
dfs = func(node *Subsystem) {
for _, p := range node.Parents {
if p == subsystem {
panic("loop in the parents relation")
}
if _, visited := ret[p]; !visited {
ret[p] = struct{}{}
dfs(p)
}
}
}
dfs(subsystem)
return ret
}
// Emails returns the list of emails related to the subsystem.
func (subsystem *Subsystem) Emails() []string {
ret := []string{}
// For the subsystem itself, we take both lists and maintainers.
ret = append(ret, subsystem.Lists...)
ret = append(ret, subsystem.Maintainers...)
// For its parent subsystems, we only take lists.
for parent := range subsystem.ReachableParents() {
if !parent.NoIndirectCc {
ret = append(ret, parent.Lists...)
}
}
return ret
}
func FilterList(list []*Subsystem, filter func(*Subsystem) bool) []*Subsystem {
keep := map[*Subsystem]bool{}
for _, item := range list {
keep[item] = filter(item)
}
newList := []*Subsystem{}
for _, item := range list {
if !keep[item] {
continue
}
newParents := []*Subsystem{}
for _, p := range item.Parents {
if keep[p] {
newParents = append(newParents, p)
}
}
item.Parents = newParents
newList = append(newList, item)
}
return newList
}
// PathRule describes the part of the directory tree belonging to a single subsystem.
type PathRule struct {
IncludeRegexp string
// ExcludeRegexps are tested before IncludeRegexp.
ExcludeRegexp string
}
func (pr *PathRule) IsEmpty() bool {
return pr.IncludeRegexp == "" && pr.ExcludeRegexp == ""
}
type DebugInfo struct {
ParentChildComment map[*Subsystem]map[*Subsystem]string
FileLists map[*Subsystem][]string
}
|