import re


def parse_db(lines, filename='-'):
    """
    Parse a db from memory. The parameter `lines` should be an iterable of
    strings representing lines of a db file.

    The `filename` parameter is used in possible parsing failure messages.
    """

    entries = {}

    it = iter(enumerate(lines, 1))

    try:
        while True:
            lineno, l = next(it)
            l = l.rstrip()

            if l.startswith('#') or not l:
                continue

            match = re.match(r'^(?P<name>.*):(?: (?P<info>.*))? +(?P<pw>[^ ]+)$', l)

            if match:
                entries[match.group('name')] = match.group('pw', 'info')
                continue

            if not l.endswith(':'):
                raise Exception('Parsing Failed: "{}" line {}'.format(filename, lineno))

            name = l[:-1]
            lineno, l = next(it)
            l = l.rstrip()
            match = re.match(r'^  (?:(?P<info>.*) +)?(?P<pw>[^ ]+)$', l)

            if match:
                entries[name] = match.group('pw', 'info')
                continue
            else:
                raise Exception('Parsing Failed: "{}" line {}'.format(filename, lineno))

    except StopIteration:
        pass

    return entries