SILENT KILLERPanel

Current Path: > > opt > alt > python39 > lib64 > python3.9


Operation   : Linux premium131.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64
Software     : Apache
Server IP    : 162.0.232.56 | Your IP: 216.73.216.111
Domains      : 1034 Domain(s)
Permission   : [ 0755 ]

Files and Folders in: //opt/alt/python39/lib64/python3.9

NameTypeSizeLast ModifiedActions
__pycache__ Directory - -
asyncio Directory - -
collections Directory - -
concurrent Directory - -
config-3.9-x86_64-linux-gnu Directory - -
ctypes Directory - -
curses Directory - -
dbm Directory - -
distutils Directory - -
email Directory - -
encodings Directory - -
ensurepip Directory - -
html Directory - -
http Directory - -
importlib Directory - -
json Directory - -
lib-dynload Directory - -
lib2to3 Directory - -
logging Directory - -
multiprocessing Directory - -
pydoc_data Directory - -
site-packages Directory - -
sqlite3 Directory - -
unittest Directory - -
urllib Directory - -
venv Directory - -
wsgiref Directory - -
xml Directory - -
xmlrpc Directory - -
zoneinfo Directory - -
LICENSE.txt File 13937 bytes June 03 2025 18:47:52.
__future__.py File 5147 bytes June 03 2025 18:47:52.
__phello__.foo.py File 64 bytes June 03 2025 18:47:52.
_aix_support.py File 3389 bytes June 03 2025 18:47:52.
_bootlocale.py File 1801 bytes June 03 2025 18:47:52.
_bootsubprocess.py File 2675 bytes June 03 2025 18:47:52.
_collections_abc.py File 29374 bytes June 03 2025 18:47:52.
_compat_pickle.py File 8749 bytes June 03 2025 18:47:52.
_compression.py File 5340 bytes June 03 2025 18:47:52.
_markupbase.py File 14623 bytes June 03 2025 18:47:52.
_osx_support.py File 21773 bytes June 03 2025 18:47:52.
_py_abc.py File 6189 bytes June 03 2025 18:47:52.
_pydecimal.py File 228666 bytes June 03 2025 18:47:52.
_pyio.py File 93316 bytes June 03 2025 18:47:52.
_sitebuiltins.py File 3115 bytes June 03 2025 18:47:52.
_strptime.py File 25277 bytes June 03 2025 18:47:52.
_sysconfigdata__linux_x86_64-linux-gnu.py File 40536 bytes June 19 2025 12:09:48.
_sysconfigdata_d_linux_x86_64-linux-gnu.py File 40272 bytes June 19 2025 12:00:02.
_threading_local.py File 7220 bytes June 03 2025 18:47:52.
_weakrefset.py File 5923 bytes June 03 2025 18:47:52.
abc.py File 4920 bytes June 03 2025 18:47:52.
aifc.py File 32605 bytes June 03 2025 18:47:52.
antigravity.py File 500 bytes June 03 2025 18:47:52.
argparse.py File 98119 bytes June 03 2025 18:47:52.
ast.py File 56256 bytes June 03 2025 18:47:52.
asynchat.py File 11321 bytes June 03 2025 18:47:52.
asyncore.py File 20102 bytes June 03 2025 18:47:52.
base64.py File 19872 bytes June 03 2025 18:47:52.
bdb.py File 31389 bytes June 03 2025 18:47:52.
binhex.py File 14784 bytes June 03 2025 18:47:52.
bisect.py File 2350 bytes June 03 2025 18:47:52.
bz2.py File 12447 bytes June 03 2025 18:47:52.
cProfile.py File 6358 bytes June 03 2025 18:47:52.
calendar.py File 24832 bytes June 03 2025 18:47:52.
cgi.py File 33945 bytes June 03 2025 18:47:52.
cgitb.py File 12096 bytes June 03 2025 18:47:52.
chunk.py File 5435 bytes June 03 2025 18:47:52.
cmd.py File 14860 bytes June 03 2025 18:47:52.
code.py File 10622 bytes June 03 2025 18:47:52.
codecs.py File 36673 bytes June 03 2025 18:47:52.
codeop.py File 6326 bytes June 03 2025 18:47:52.
colorsys.py File 4064 bytes June 03 2025 18:47:52.
compileall.py File 20105 bytes June 03 2025 18:47:52.
configparser.py File 54584 bytes June 03 2025 18:47:52.
contextlib.py File 24624 bytes June 03 2025 18:47:52.
contextvars.py File 129 bytes June 03 2025 18:47:52.
copy.py File 8650 bytes June 03 2025 18:47:52.
copyreg.py File 7274 bytes June 03 2025 18:47:52.
crypt.py File 3819 bytes June 03 2025 18:47:52.
csv.py File 16144 bytes June 03 2025 18:47:52.
dataclasses.py File 49586 bytes June 03 2025 18:47:52.
datetime.py File 89177 bytes June 03 2025 18:47:52.
decimal.py File 320 bytes June 03 2025 18:47:52.
difflib.py File 83307 bytes June 03 2025 18:47:52.
dis.py File 20570 bytes June 03 2025 18:47:52.
doctest.py File 104568 bytes June 03 2025 18:47:52.
enum.py File 39440 bytes June 03 2025 18:47:52.
filecmp.py File 10024 bytes June 03 2025 18:47:52.
fileinput.py File 14791 bytes June 03 2025 18:47:52.
fnmatch.py File 6004 bytes June 03 2025 18:47:52.
formatter.py File 15143 bytes June 03 2025 18:47:52.
fractions.py File 24323 bytes June 03 2025 18:47:52.
ftplib.py File 35496 bytes June 03 2025 18:47:52.
functools.py File 38881 bytes June 03 2025 18:47:52.
genericpath.py File 5246 bytes June 03 2025 18:47:52.
getopt.py File 7489 bytes June 03 2025 18:47:52.
getpass.py File 5990 bytes June 03 2025 18:47:52.
gettext.py File 27266 bytes June 03 2025 18:47:52.
glob.py File 5823 bytes June 03 2025 18:47:52.
graphlib.py File 9573 bytes June 03 2025 18:47:52.
gzip.py File 21772 bytes June 03 2025 18:47:52.
hashlib.py File 10010 bytes June 03 2025 18:47:52.
heapq.py File 22877 bytes June 03 2025 18:47:52.
hmac.py File 7003 bytes June 03 2025 18:47:52.
imaplib.py File 55256 bytes June 03 2025 18:47:52.
imghdr.py File 3808 bytes June 03 2025 18:47:52.
imp.py File 10536 bytes June 03 2025 18:47:52.
inspect.py File 118235 bytes June 03 2025 18:47:52.
io.py File 3541 bytes June 03 2025 18:47:52.
ipaddress.py File 80924 bytes June 03 2025 18:47:52.
keyword.py File 1047 bytes June 03 2025 18:47:52.
linecache.py File 5461 bytes June 03 2025 18:47:52.
locale.py File 78271 bytes June 03 2025 18:47:52.
lzma.py File 13231 bytes June 03 2025 18:47:52.
mailbox.py File 78794 bytes June 03 2025 18:47:52.
mailcap.py File 9116 bytes June 03 2025 18:47:52.
mimetypes.py File 21564 bytes June 03 2025 18:47:52.
modulefinder.py File 24401 bytes June 03 2025 18:47:52.
netrc.py File 5566 bytes June 03 2025 18:47:52.
nntplib.py File 41023 bytes June 03 2025 18:47:52.
ntpath.py File 28259 bytes June 03 2025 18:47:52.
nturl2path.py File 2887 bytes June 03 2025 18:47:52.
numbers.py File 10338 bytes June 03 2025 18:47:52.
opcode.py File 5660 bytes June 03 2025 18:47:52.
operator.py File 10751 bytes June 03 2025 18:47:52.
optparse.py File 60369 bytes June 03 2025 18:47:52.
os.py File 39065 bytes June 03 2025 18:47:52.
pathlib.py File 51134 bytes June 03 2025 18:47:52.
pdb.py File 63250 bytes June 03 2025 18:47:52.
pickle.py File 64920 bytes June 03 2025 18:47:52.
pickletools.py File 93486 bytes June 03 2025 18:47:52.
pipes.py File 8916 bytes June 03 2025 18:47:52.
pkgutil.py File 24276 bytes June 03 2025 18:47:52.
platform.py File 40614 bytes June 03 2025 18:47:52.
plistlib.py File 28248 bytes June 03 2025 18:47:52.
poplib.py File 15198 bytes June 03 2025 18:47:52.
posixpath.py File 16273 bytes June 03 2025 18:47:52.
pprint.py File 22527 bytes June 03 2025 18:47:52.
profile.py File 22894 bytes June 03 2025 18:47:52.
pstats.py File 29326 bytes June 03 2025 18:47:52.
pty.py File 4807 bytes June 03 2025 18:47:52.
py_compile.py File 8203 bytes June 19 2025 11:56:56.
pyclbr.py File 15255 bytes June 03 2025 18:47:52.
pydoc.py File 109612 bytes June 03 2025 18:47:52.
queue.py File 11496 bytes June 03 2025 18:47:52.
quopri.py File 7279 bytes June 03 2025 18:47:52.
random.py File 31484 bytes June 03 2025 18:47:52.
re.py File 15861 bytes June 03 2025 18:47:52.
reprlib.py File 5267 bytes June 03 2025 18:47:52.
rlcompleter.py File 7648 bytes June 03 2025 18:47:52.
runpy.py File 13084 bytes June 03 2025 18:47:52.
sched.py File 6442 bytes June 03 2025 18:47:52.
secrets.py File 2036 bytes June 03 2025 18:47:52.
selectors.py File 19536 bytes June 03 2025 18:47:52.
shelve.py File 8527 bytes June 03 2025 18:47:52.
shlex.py File 13501 bytes June 03 2025 18:47:52.
shutil.py File 53030 bytes June 03 2025 18:47:52.
signal.py File 2438 bytes June 03 2025 18:47:52.
site.py File 21844 bytes June 03 2025 18:47:52.
smtpd.py File 34834 bytes June 03 2025 18:47:52.
smtplib.py File 45418 bytes June 03 2025 18:47:52.
sndhdr.py File 7099 bytes June 03 2025 18:47:52.
socket.py File 36915 bytes June 03 2025 18:47:52.
socketserver.py File 27296 bytes June 03 2025 18:47:52.
sre_compile.py File 27973 bytes June 03 2025 18:47:52.
sre_constants.py File 7177 bytes June 03 2025 18:47:52.
sre_parse.py File 40779 bytes June 03 2025 18:47:52.
ssl.py File 52530 bytes June 03 2025 18:47:52.
stat.py File 5485 bytes June 03 2025 18:47:52.
statistics.py File 38067 bytes June 03 2025 18:47:52.
string.py File 10566 bytes June 03 2025 18:47:52.
stringprep.py File 12917 bytes June 03 2025 18:47:52.
struct.py File 257 bytes June 03 2025 18:47:52.
subprocess.py File 83564 bytes June 03 2025 18:47:52.
sunau.py File 18158 bytes June 03 2025 18:47:52.
symbol.py File 2281 bytes June 19 2025 12:01:19.
symtable.py File 7905 bytes June 03 2025 18:47:52.
sysconfig.py File 24914 bytes June 03 2025 18:47:52.
tabnanny.py File 11419 bytes June 03 2025 18:47:52.
tarfile.py File 110849 bytes June 03 2025 18:47:52.
telnetlib.py File 23254 bytes June 03 2025 18:47:52.
tempfile.py File 27963 bytes June 03 2025 18:47:52.
textwrap.py File 19407 bytes June 03 2025 18:47:52.
this.py File 1003 bytes June 03 2025 18:47:52.
threading.py File 54176 bytes June 03 2025 18:47:52.
timeit.py File 13493 bytes June 03 2025 18:47:52.
token.py File 2368 bytes June 03 2025 18:47:52.
tokenize.py File 25883 bytes June 03 2025 18:47:52.
trace.py File 29220 bytes June 03 2025 18:47:52.
traceback.py File 24660 bytes June 03 2025 18:47:52.
tracemalloc.py File 18047 bytes June 03 2025 18:47:52.
tty.py File 879 bytes June 03 2025 18:47:52.
types.py File 9785 bytes June 03 2025 18:47:52.
typing.py File 77044 bytes June 03 2025 18:47:52.
uu.py File 7277 bytes June 19 2025 12:10:58.
uuid.py File 27324 bytes June 03 2025 18:47:52.
warnings.py File 19688 bytes June 03 2025 18:47:52.
wave.py File 18004 bytes June 03 2025 18:47:52.
weakref.py File 21560 bytes June 03 2025 18:47:52.
webbrowser.py File 24096 bytes June 03 2025 18:47:52.
xdrlib.py File 5913 bytes June 03 2025 18:47:52.
zipapp.py File 7535 bytes June 03 2025 18:47:52.
zipfile.py File 88240 bytes June 03 2025 18:47:52.
zipimport.py File 30765 bytes June 03 2025 18:47:52.

Reading File: //opt/alt/python39/lib64/python3.9/_markupbase.py

"""Shared support for scanning document type declarations in HTML and XHTML.

This module is used as a foundation for the html.parser module.  It has no
documented public API and should not be used directly.

"""

import re

_declname_match = re.compile(r'[a-zA-Z][-_.a-zA-Z0-9]*\s*').match
_declstringlit_match = re.compile(r'(\'[^\']*\'|"[^"]*")\s*').match
_commentclose = re.compile(r'--\s*>')
_markedsectionclose = re.compile(r']\s*]\s*>')

# An analysis of the MS-Word extensions is available at
# http://www.planetpublish.com/xmlarena/xap/Thursday/WordtoXML.pdf

_msmarkedsectionclose = re.compile(r']\s*>')

del re


class ParserBase:
    """Parser base class which provides some common support methods used
    by the SGML/HTML and XHTML parsers."""

    def __init__(self):
        if self.__class__ is ParserBase:
            raise RuntimeError(
                "_markupbase.ParserBase must be subclassed")

    def error(self, message):
        raise NotImplementedError(
            "subclasses of ParserBase must override error()")

    def reset(self):
        self.lineno = 1
        self.offset = 0

    def getpos(self):
        """Return current line number and offset."""
        return self.lineno, self.offset

    # Internal -- update line number and offset.  This should be
    # called for each piece of data exactly once, in order -- in other
    # words the concatenation of all the input strings to this
    # function should be exactly the entire input.
    def updatepos(self, i, j):
        if i >= j:
            return j
        rawdata = self.rawdata
        nlines = rawdata.count("\n", i, j)
        if nlines:
            self.lineno = self.lineno + nlines
            pos = rawdata.rindex("\n", i, j) # Should not fail
            self.offset = j-(pos+1)
        else:
            self.offset = self.offset + j-i
        return j

    _decl_otherchars = ''

    # Internal -- parse declaration (for use by subclasses).
    def parse_declaration(self, i):
        # This is some sort of declaration; in "HTML as
        # deployed," this should only be the document type
        # declaration ("<!DOCTYPE html...>").
        # ISO 8879:1986, however, has more complex
        # declaration syntax for elements in <!...>, including:
        # --comment--
        # [marked section]
        # name in the following list: ENTITY, DOCTYPE, ELEMENT,
        # ATTLIST, NOTATION, SHORTREF, USEMAP,
        # LINKTYPE, LINK, IDLINK, USELINK, SYSTEM
        rawdata = self.rawdata
        j = i + 2
        assert rawdata[i:j] == "<!", "unexpected call to parse_declaration"
        if rawdata[j:j+1] == ">":
            # the empty comment <!>
            return j + 1
        if rawdata[j:j+1] in ("-", ""):
            # Start of comment followed by buffer boundary,
            # or just a buffer boundary.
            return -1
        # A simple, practical version could look like: ((name|stringlit) S*) + '>'
        n = len(rawdata)
        if rawdata[j:j+2] == '--': #comment
            # Locate --.*-- as the body of the comment
            return self.parse_comment(i)
        elif rawdata[j] == '[': #marked section
            # Locate [statusWord [...arbitrary SGML...]] as the body of the marked section
            # Where statusWord is one of TEMP, CDATA, IGNORE, INCLUDE, RCDATA
            # Note that this is extended by Microsoft Office "Save as Web" function
            # to include [if...] and [endif].
            return self.parse_marked_section(i)
        else: #all other declaration elements
            decltype, j = self._scan_name(j, i)
        if j < 0:
            return j
        if decltype == "doctype":
            self._decl_otherchars = ''
        while j < n:
            c = rawdata[j]
            if c == ">":
                # end of declaration syntax
                data = rawdata[i+2:j]
                if decltype == "doctype":
                    self.handle_decl(data)
                else:
                    # According to the HTML5 specs sections "8.2.4.44 Bogus
                    # comment state" and "8.2.4.45 Markup declaration open
                    # state", a comment token should be emitted.
                    # Calling unknown_decl provides more flexibility though.
                    self.unknown_decl(data)
                return j + 1
            if c in "\"'":
                m = _declstringlit_match(rawdata, j)
                if not m:
                    return -1 # incomplete
                j = m.end()
            elif c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ":
                name, j = self._scan_name(j, i)
            elif c in self._decl_otherchars:
                j = j + 1
            elif c == "[":
                # this could be handled in a separate doctype parser
                if decltype == "doctype":
                    j = self._parse_doctype_subset(j + 1, i)
                elif decltype in {"attlist", "linktype", "link", "element"}:
                    # must tolerate []'d groups in a content model in an element declaration
                    # also in data attribute specifications of attlist declaration
                    # also link type declaration subsets in linktype declarations
                    # also link attribute specification lists in link declarations
                    self.error("unsupported '[' char in %s declaration" % decltype)
                else:
                    self.error("unexpected '[' char in declaration")
            else:
                self.error(
                    "unexpected %r char in declaration" % rawdata[j])
            if j < 0:
                return j
        return -1 # incomplete

    # Internal -- parse a marked section
    # Override this to handle MS-word extension syntax <![if word]>content<![endif]>
    def parse_marked_section(self, i, report=1):
        rawdata= self.rawdata
        assert rawdata[i:i+3] == '<![', "unexpected call to parse_marked_section()"
        sectName, j = self._scan_name( i+3, i )
        if j < 0:
            return j
        if sectName in {"temp", "cdata", "ignore", "include", "rcdata"}:
            # look for standard ]]> ending
            match= _markedsectionclose.search(rawdata, i+3)
        elif sectName in {"if", "else", "endif"}:
            # look for MS Office ]> ending
            match= _msmarkedsectionclose.search(rawdata, i+3)
        else:
            self.error('unknown status keyword %r in marked section' % rawdata[i+3:j])
            match = None
        if not match:
            return -1
        if report:
            j = match.start(0)
            self.unknown_decl(rawdata[i+3: j])
        return match.end(0)

    # Internal -- parse comment, return length or -1 if not terminated
    def parse_comment(self, i, report=1):
        rawdata = self.rawdata
        if rawdata[i:i+4] != '<!--':
            self.error('unexpected call to parse_comment()')
        match = _commentclose.search(rawdata, i+4)
        if not match:
            return -1
        if report:
            j = match.start(0)
            self.handle_comment(rawdata[i+4: j])
        return match.end(0)

    # Internal -- scan past the internal subset in a <!DOCTYPE declaration,
    # returning the index just past any whitespace following the trailing ']'.
    def _parse_doctype_subset(self, i, declstartpos):
        rawdata = self.rawdata
        n = len(rawdata)
        j = i
        while j < n:
            c = rawdata[j]
            if c == "<":
                s = rawdata[j:j+2]
                if s == "<":
                    # end of buffer; incomplete
                    return -1
                if s != "<!":
                    self.updatepos(declstartpos, j + 1)
                    self.error("unexpected char in internal subset (in %r)" % s)
                if (j + 2) == n:
                    # end of buffer; incomplete
                    return -1
                if (j + 4) > n:
                    # end of buffer; incomplete
                    return -1
                if rawdata[j:j+4] == "<!--":
                    j = self.parse_comment(j, report=0)
                    if j < 0:
                        return j
                    continue
                name, j = self._scan_name(j + 2, declstartpos)
                if j == -1:
                    return -1
                if name not in {"attlist", "element", "entity", "notation"}:
                    self.updatepos(declstartpos, j + 2)
                    self.error(
                        "unknown declaration %r in internal subset" % name)
                # handle the individual names
                meth = getattr(self, "_parse_doctype_" + name)
                j = meth(j, declstartpos)
                if j < 0:
                    return j
            elif c == "%":
                # parameter entity reference
                if (j + 1) == n:
                    # end of buffer; incomplete
                    return -1
                s, j = self._scan_name(j + 1, declstartpos)
                if j < 0:
                    return j
                if rawdata[j] == ";":
                    j = j + 1
            elif c == "]":
                j = j + 1
                while j < n and rawdata[j].isspace():
                    j = j + 1
                if j < n:
                    if rawdata[j] == ">":
                        return j
                    self.updatepos(declstartpos, j)
                    self.error("unexpected char after internal subset")
                else:
                    return -1
            elif c.isspace():
                j = j + 1
            else:
                self.updatepos(declstartpos, j)
                self.error("unexpected char %r in internal subset" % c)
        # end of buffer reached
        return -1

    # Internal -- scan past <!ELEMENT declarations
    def _parse_doctype_element(self, i, declstartpos):
        name, j = self._scan_name(i, declstartpos)
        if j == -1:
            return -1
        # style content model; just skip until '>'
        rawdata = self.rawdata
        if '>' in rawdata[j:]:
            return rawdata.find(">", j) + 1
        return -1

    # Internal -- scan past <!ATTLIST declarations
    def _parse_doctype_attlist(self, i, declstartpos):
        rawdata = self.rawdata
        name, j = self._scan_name(i, declstartpos)
        c = rawdata[j:j+1]
        if c == "":
            return -1
        if c == ">":
            return j + 1
        while 1:
            # scan a series of attribute descriptions; simplified:
            #   name type [value] [#constraint]
            name, j = self._scan_name(j, declstartpos)
            if j < 0:
                return j
            c = rawdata[j:j+1]
            if c == "":
                return -1
            if c == "(":
                # an enumerated type; look for ')'
                if ")" in rawdata[j:]:
                    j = rawdata.find(")", j) + 1
                else:
                    return -1
                while rawdata[j:j+1].isspace():
                    j = j + 1
                if not rawdata[j:]:
                    # end of buffer, incomplete
                    return -1
            else:
                name, j = self._scan_name(j, declstartpos)
            c = rawdata[j:j+1]
            if not c:
                return -1
            if c in "'\"":
                m = _declstringlit_match(rawdata, j)
                if m:
                    j = m.end()
                else:
                    return -1
                c = rawdata[j:j+1]
                if not c:
                    return -1
            if c == "#":
                if rawdata[j:] == "#":
                    # end of buffer
                    return -1
                name, j = self._scan_name(j + 1, declstartpos)
                if j < 0:
                    return j
                c = rawdata[j:j+1]
                if not c:
                    return -1
            if c == '>':
                # all done
                return j + 1

    # Internal -- scan past <!NOTATION declarations
    def _parse_doctype_notation(self, i, declstartpos):
        name, j = self._scan_name(i, declstartpos)
        if j < 0:
            return j
        rawdata = self.rawdata
        while 1:
            c = rawdata[j:j+1]
            if not c:
                # end of buffer; incomplete
                return -1
            if c == '>':
                return j + 1
            if c in "'\"":
                m = _declstringlit_match(rawdata, j)
                if not m:
                    return -1
                j = m.end()
            else:
                name, j = self._scan_name(j, declstartpos)
                if j < 0:
                    return j

    # Internal -- scan past <!ENTITY declarations
    def _parse_doctype_entity(self, i, declstartpos):
        rawdata = self.rawdata
        if rawdata[i:i+1] == "%":
            j = i + 1
            while 1:
                c = rawdata[j:j+1]
                if not c:
                    return -1
                if c.isspace():
                    j = j + 1
                else:
                    break
        else:
            j = i
        name, j = self._scan_name(j, declstartpos)
        if j < 0:
            return j
        while 1:
            c = self.rawdata[j:j+1]
            if not c:
                return -1
            if c in "'\"":
                m = _declstringlit_match(rawdata, j)
                if m:
                    j = m.end()
                else:
                    return -1    # incomplete
            elif c == ">":
                return j + 1
            else:
                name, j = self._scan_name(j, declstartpos)
                if j < 0:
                    return j

    # Internal -- scan a name token and the new position and the token, or
    # return -1 if we've reached the end of the buffer.
    def _scan_name(self, i, declstartpos):
        rawdata = self.rawdata
        n = len(rawdata)
        if i == n:
            return None, -1
        m = _declname_match(rawdata, i)
        if m:
            s = m.group()
            name = s.strip()
            if (i + len(s)) == n:
                return None, -1  # end of buffer
            return name.lower(), m.end()
        else:
            self.updatepos(declstartpos, i)
            self.error("expected name token at %r"
                       % rawdata[declstartpos:declstartpos+20])

    # To be overridden -- handlers for unknown objects
    def unknown_decl(self, data):
        pass

SILENT KILLER Tool