Currently, NestedMatch has very limited support for aguments replacement: it is all or nothing.
Add support to allow replacing individual arguments as well. Signed-off-by: Mauro Carvalho Chehab <[email protected]> --- tools/lib/python/kdoc/kdoc_re.py | 84 ++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/tools/lib/python/kdoc/kdoc_re.py b/tools/lib/python/kdoc/kdoc_re.py index e34d55c25680..858cc688a58f 100644 --- a/tools/lib/python/kdoc/kdoc_re.py +++ b/tools/lib/python/kdoc/kdoc_re.py @@ -177,29 +177,6 @@ class NestedMatch: will ignore the search string. """ - # TODO: make NestedMatch handle multiple match groups - # - # Right now, regular expressions to match it are defined only up to - # the start delimiter, e.g.: - # - # \bSTRUCT_GROUP\( - # - # is similar to: STRUCT_GROUP\((.*)\) - # except that the content inside the match group is delimiter-aligned. - # - # The content inside parentheses is converted into a single replace - # group (e.g. r`\1'). - # - # It would be nice to change such definition to support multiple - # match groups, allowing a regex equivalent to: - # - # FOO\((.*), (.*), (.*)\) - # - # it is probably easier to define it not as a regular expression, but - # with some lexical definition like: - # - # FOO(arg1, arg2, arg3) - def __init__(self, regex): self.regex = KernRe(regex) @@ -285,6 +262,59 @@ class NestedMatch: yield line[t[0]:t[2]] + @staticmethod + def _split_args(all_args, delim=","): + """ + Helper method to split comma-separated function arguments + or struct elements, if delim is set to ";". + + It returns a list of arguments that can be used later on by + the sub() method. + """ + args = [all_args] + stack = [] + arg_start = 0 + string_char = None + escape = False + + for idx, d in enumerate(all_args): + if escape: + escape = False + continue + + if string_char: + if d == '\\': + escape = True + elif d == string_char: + string_char = None + + continue + + if d in ('"', "'"): + string_char = d + continue + + if d in DELIMITER_PAIRS: + end = DELIMITER_PAIRS[d] + + stack.append(end) + continue + + if stack and d == stack[-1]: + stack.pop() + continue + + if d == delim and not stack: + args.append(all_args[arg_start:idx].strip()) + arg_start = idx + 1 + + # Add the last argument (if any) + last = all_args[arg_start:].strip() + if last: + args.append(last) + + return args + def sub(self, sub, line, count=0): """ This is similar to re.sub: @@ -310,9 +340,13 @@ class NestedMatch: # Value, ignoring start/end delimiters value = line[end:pos - 1] - # replaces \0 at the sub string, if \0 is used there + # replace arguments new_sub = sub - new_sub = new_sub.replace(r'\0', value) + if "\\" in sub: + args = self._split_args(value) + + new_sub = re.sub(r'\\(\d+)', + lambda m: args[int(m.group(1))], new_sub) out += new_sub -- 2.52.0
