'Helper function. This is normally only called when the
lockstring is cached and does preliminary checking.  locks are
stored as a string
atype:[NOT] lock()[[ AND|OR [NOT] lock()[...]];atype...
Args:
storage_locksring (str): The lockstring to parse.'

def _parse_lockstring(self, storage_lockstring):

    locks = {}
    if (not storage_lockstring):
        return locks
    duplicates = 0
    elist = []
    wlist = []
    for raw_lockstring in storage_lockstring.split(';'):
        if (not raw_lockstring):
            continue
        lock_funcs = []
        try:
            (access_type, rhs) = (part.strip() for part in raw_lockstring.split(':', 1))
        except ValueError:
            logger.log_trace()
            return locks
        funclist = _RE_FUNCS.findall(rhs)
        evalstring = rhs
        for pattern in ('AND', 'OR', 'NOT'):
            evalstring = re.sub(('\\b%s\\b' % pattern), pattern.lower(), evalstring)
        nfuncs = len(funclist)
        for funcstring in funclist:
            (funcname, rest) = (part.strip().strip(')') for part in funcstring.split('(', 1))
            func = _LOCKFUNCS.get(funcname, None)
            if (not callable(func)):
                elist.append((_("Lock:    lock-function    '%s'    is    not    available.") % funcstring))
                continue
            args = list((arg.strip() for arg in rest.split(',') if (arg and (not ('=' in arg)))))
            kwargs = dict([arg.split('=', 1) for arg in rest.split(',') if (arg and ('=' in arg))])
            lock_funcs.append((func, args, kwargs))
            evalstring = evalstring.replace(funcstring, '%s')
        if (len(lock_funcs) < nfuncs):
            continue
        try:
            evalstring = '    '.join(_RE_OK.findall(evalstring))
            eval((evalstring % tuple((True for func in funclist))), {}, {})
        except Exception:
            elist.append((_("Lock:    definition    '%s'    has    syntax    errors.") % raw_lockstring))
            continue
        if (access_type in locks):
            duplicates += 1
            wlist.append(_(("LockHandler    on    %(obj)s:    access    type    '%(access_type)s'    changed    from    '%(source)s'    to    '%(goal)s'    " % {'obj': self.obj, 'access_type': access_type, 'source': locks[access_type][2], 'goal': raw_lockstring})))
        locks[access_type] = (evalstring, tuple(lock_funcs), raw_lockstring)
    if (wlist and WARNING_LOG):
        logger.log_file('\n'.join(wlist), WARNING_LOG)
    if elist:
        raise LockException('\n'.join(elist))
    return locks
