def match_path(filename: str, pattern: str) -> bool:
    '''recursive glob match for editorconfig sections'''
    index = 0
    num_ranges: T.List[T.Tuple[int, int]] = []

    def curl_replace(m: re.Match) -> str:
        nonlocal index

        if '\\.\\.' in m[1]:
            index += 1
            low, high = m[1].split('\\.\\.')
            num_ranges.append((int(low), int(high)))
            return f'(?P<num{index}>-?[0-9]+)'
        else:
            return T.cast(str, m[1].replace(',', '|'))

    pattern_re = pattern.replace('.', '\\.')
    pattern_re = re.sub(r'(?<!\\)\?', '.', pattern_re)  # ? -> .
    pattern_re = re.sub(r'(?<![\\\*])\*(?!\*)', '([^/]*)', pattern_re)  # * -> ([^/]*)
    pattern_re = re.sub(r'(?<!\\)\*\*', '(.*)', pattern_re)  # ** -> (.*)
    pattern_re = re.sub(r'(?<!\\)\[!(.*?[^\\])\]', r'([^\1])', pattern_re)  # [!name] -> [^name]
    pattern_re = re.sub(r'(?<!\\)\{(.*?[^\\])}', curl_replace, pattern_re)  # {}
    if pattern.startswith('/'):
        pattern_re = '^' + pattern_re
    pattern_re += '$'

    m = re.search(pattern_re, filename)
    if m is None:
        return False

    for i in range(index):
        try:
            val = int(m[f'num{i+1}'])
            if not num_ranges[i][0] <= val <= num_ranges[i][1]:
                return False
        except ValueError:
            return False

    return True
recursive glob match for editorconfig sections
mesonbuild/mformat.py