add backtracking irc glob matching

This commit is contained in:
jesopo 2020-04-27 23:26:41 +01:00
parent 0921cb8086
commit ab66df4d43
2 changed files with 46 additions and 2 deletions

View file

@ -18,3 +18,37 @@ def _collapse(pattern: str) -> str:
i += 1
return out
def _match(pattern: str, s: str):
i, j = 0, 0
i_backup = -1
j_backup = -1
while j < len(s):
p = (pattern[i:] or [None])[0]
if p == "*":
i += 1
i_backup = i
j_backup = j
elif p in ["?", s[j]]:
i += 1
j += 1
else:
if i_backup == -1:
return False
else:
j_backup += 1
j = j_backup
i = i_backup
return i == len(pattern)
class Glob(object):
def __init__(self, pattern: str):
self._pattern = pattern
def match(self, s: str) -> bool:
return _match(self._pattern, s)
def compile(pattern: str):
return Glob(_collapse(pattern))

View file

@ -1,7 +1,8 @@
from re import compile
from re import compile as re_compile
from typing import Optional, Pattern
from irctokens import Hostmask
from ..interface import IMatchResponseParam, IMatchResponseHostmask, IServer
from ..glob import Glob, compile as glob_compile
from .. import formatting
class Any(IMatchResponseParam):
@ -52,7 +53,7 @@ class Regex(IMatchResponseParam):
self._pattern: Optional[Pattern] = None
def match(self, server: IServer, arg: str) -> bool:
if self._pattern is None:
self._pattern = compile(self._value)
self._pattern = re_compile(self._value)
return bool(self._pattern.search(arg))
class Nickname(IMatchResponseHostmask):
@ -67,3 +68,12 @@ class Nickname(IMatchResponseHostmask):
if self._folded is None:
self._folded = server.casefold(self._nickname)
return self._folded == server.casefold(hostmask.nickname)
class Mask(IMatchResponseHostmask):
def __init__(self, mask: str):
self._mask = mask
self._compiled = Optional[Glob]
def match(self, server: IServer, hostmask: Hostmask):
if self._compiled is None:
self._compiled = glob_compile(self._mask)
return self._compiled.match(str(hostmask))