Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/usr/bin/env python3
2# SPDX-License-Identifier: GPL-2.0
3# Copyright(c) 2025: Mauro Carvalho Chehab <mchehab@kernel.org>.
4
5"""
6Regular expression ancillary classes.
7
8Those help caching regular expressions and do matching for kernel-doc.
9"""
10
11import re
12
13# Local cache for regular expressions
14re_cache = {}
15
16
17class KernRe:
18 """
19 Helper class to simplify regex declaration and usage.
20
21 It calls re.compile for a given pattern. It also allows adding
22 regular expressions and define sub at class init time.
23
24 Regular expressions can be cached via an argument, helping to speedup
25 searches.
26 """
27
28 def _add_regex(self, string, flags):
29 """
30 Adds a new regex or reuses it from the cache.
31 """
32 self.regex = re_cache.get(string, None)
33 if not self.regex:
34 self.regex = re.compile(string, flags=flags)
35 if self.cache:
36 re_cache[string] = self.regex
37
38 def __init__(self, string, cache=True, flags=0):
39 """
40 Compile a regular expression and initialize internal vars.
41 """
42
43 self.cache = cache
44 self.last_match = None
45
46 self._add_regex(string, flags)
47
48 def __str__(self):
49 """
50 Return the regular expression pattern.
51 """
52 return self.regex.pattern
53
54 def __repr__(self):
55 """
56 Returns a displayable version of the class init.
57 """
58
59 flag_map = {
60 re.IGNORECASE: "re.I",
61 re.MULTILINE: "re.M",
62 re.DOTALL: "re.S",
63 re.VERBOSE: "re.X",
64 }
65
66 flags = []
67 for flag, name in flag_map.items():
68 if self.regex.flags & flag:
69 flags.append(name)
70
71 flags_name = " | ".join(flags)
72
73 max_len = 60
74 pattern = ""
75 for pos in range(0, len(self.regex.pattern), max_len):
76 pattern += '"' + self.regex.pattern[pos:max_len + pos] + '" '
77
78 if flags_name:
79 return f'KernRe({pattern}, {flags_name})'
80 else:
81 return f'KernRe({pattern})'
82
83 def __add__(self, other):
84 """
85 Allows adding two regular expressions into one.
86 """
87
88 return KernRe(str(self) + str(other), cache=self.cache or other.cache,
89 flags=self.regex.flags | other.regex.flags)
90
91 def match(self, string):
92 """
93 Handles a re.match storing its results.
94 """
95
96 self.last_match = self.regex.match(string)
97 return self.last_match
98
99 def search(self, string):
100 """
101 Handles a re.search storing its results.
102 """
103
104 self.last_match = self.regex.search(string)
105 return self.last_match
106
107 def finditer(self, string):
108 """
109 Alias to re.finditer.
110 """
111
112 return self.regex.finditer(string)
113
114 def findall(self, string):
115 """
116 Alias to re.findall.
117 """
118
119 return self.regex.findall(string)
120
121 def split(self, string):
122 """
123 Alias to re.split.
124 """
125
126 return self.regex.split(string)
127
128 def sub(self, sub, string, count=0):
129 """
130 Alias to re.sub.
131 """
132
133 return self.regex.sub(sub, string, count=count)
134
135 def group(self, num):
136 """
137 Returns the group results of the last match.
138 """
139
140 return self.last_match.group(num)
141
142 def groups(self):
143 """
144 Returns the group results of the last match
145 """
146
147 return self.last_match.groups()