| #!/usr/bin/env python3 | |
| # SPDX-License-Identifier: GPL-2.0 | |
| # Copyright(c) 2025: Mauro Carvalho Chehab <mchehab@kernel.org>. | |
| """ | |
| Regular expression ancillary classes. | |
| Those help caching regular expressions and do matching for kernel-doc. | |
| """ | |
| import re | |
| # Local cache for regular expressions | |
| re_cache = {} | |
| class KernRe: | |
| """ | |
| Helper class to simplify regex declaration and usage. | |
| It calls re.compile for a given pattern. It also allows adding | |
| regular expressions and define sub at class init time. | |
| Regular expressions can be cached via an argument, helping to speedup | |
| searches. | |
| """ | |
| def _add_regex(self, string, flags): | |
| """ | |
| Adds a new regex or reuses it from the cache. | |
| """ | |
| self.regex = re_cache.get(string, None) | |
| if not self.regex: | |
| self.regex = re.compile(string, flags=flags) | |
| if self.cache: | |
| re_cache[string] = self.regex | |
| def __init__(self, string, cache=True, flags=0): | |
| """ | |
| Compile a regular expression and initialize internal vars. | |
| """ | |
| self.cache = cache | |
| self.last_match = None | |
| self._add_regex(string, flags) | |
| def __str__(self): | |
| """ | |
| Return the regular expression pattern. | |
| """ | |
| return self.regex.pattern | |
| def __repr__(self): | |
| """ | |
| Returns a displayable version of the class init. | |
| """ | |
| flag_map = { | |
| re.IGNORECASE: "re.I", | |
| re.MULTILINE: "re.M", | |
| re.DOTALL: "re.S", | |
| re.VERBOSE: "re.X", | |
| } | |
| flags = [] | |
| for flag, name in flag_map.items(): | |
| if self.regex.flags & flag: | |
| flags.append(name) | |
| flags_name = " | ".join(flags) | |
| max_len = 60 | |
| pattern = "" | |
| for pos in range(0, len(self.regex.pattern), max_len): | |
| pattern += '"' + self.regex.pattern[pos:max_len + pos] + '" ' | |
| if flags_name: | |
| return f'KernRe({pattern}, {flags_name})' | |
| else: | |
| return f'KernRe({pattern})' | |
| def __add__(self, other): | |
| """ | |
| Allows adding two regular expressions into one. | |
| """ | |
| return KernRe(str(self) + str(other), cache=self.cache or other.cache, | |
| flags=self.regex.flags | other.regex.flags) | |
| def match(self, string): | |
| """ | |
| Handles a re.match storing its results. | |
| """ | |
| self.last_match = self.regex.match(string) | |
| return self.last_match | |
| def search(self, string): | |
| """ | |
| Handles a re.search storing its results. | |
| """ | |
| self.last_match = self.regex.search(string) | |
| return self.last_match | |
| def finditer(self, string): | |
| """ | |
| Alias to re.finditer. | |
| """ | |
| return self.regex.finditer(string) | |
| def findall(self, string): | |
| """ | |
| Alias to re.findall. | |
| """ | |
| return self.regex.findall(string) | |
| def split(self, string): | |
| """ | |
| Alias to re.split. | |
| """ | |
| return self.regex.split(string) | |
| def sub(self, sub, string, count=0): | |
| """ | |
| Alias to re.sub. | |
| """ | |
| return self.regex.sub(sub, string, count=count) | |
| def group(self, num): | |
| """ | |
| Returns the group results of the last match. | |
| """ | |
| return self.last_match.group(num) | |
| def groups(self): | |
| """ | |
| Returns the group results of the last match | |
| """ | |
| return self.last_match.groups() |