Source code for epicsdbbuilder.fanout

'''Support for creating fanout records.'''

from .dbd import records
from .recordbase import PP


__all__ = ['create_fanout', 'create_dfanout']



# ----------------------------------------------------------------------------
#  Fanout record generation


# This support routine chops the given list into segments no longer than size.
def choplist(list, size):
    return [list[i:i+size] for i in range(0, len(list), size)]


# Support routine to do the work of fanout generation common to fanout and
# dfanout.
def _fanout_helper(
        fanout_name, link_list, fanout_size, record_factory,
        field_name, fixup_link, firstargs, nextargs):

    # First break the list of links into chunks small enough for each fanout
    # record.  First chop it into segments small enough to fit into each
    # fanout record, leaving room for an extra link.  The last record can take
    # an extra entry so then fix up the chopped list.
    chopped = choplist(link_list, fanout_size - 1)
    if len(chopped) > 1 and len(chopped[-1]) == 1:
        chopped[-2:] = [chopped[-2] + chopped[-1]]

    # Convert the chopped list into a list of fanout records.
    recordList = []
    args = firstargs
    for i, links in enumerate(chopped):
        # The first record gets the standard name and a different set of
        # record arguments.
        name = fanout_name
        if i > 0:
            name += str(i)
        # Build a fanout record with the computed name and arguments.
        record = record_factory(name, **args)
        args = nextargs     # Subsequent records get the other arguments
        # Link the new fanout record to the given list of links
        for i, link in enumerate(links):
            setattr(record, field_name(i), link)
        recordList.append(record)

    # Chain the fanout records together using the last field in each record:
    # we've taken care to reserve this field when we split the link list!
    next_name = field_name(fanout_size - 1)
    for prev, next in zip(recordList[:-1], recordList[1:]):
        setattr(prev, next_name, fixup_link(next))

    return recordList



[docs]def create_fanout(name, *record_list, **args): # We can only support fanout to "All" style fanout records: to generate # masked or selected fanouts we'd need to create a cluster of supporting # calc records and structure the set rather differently. args['SELM'] = 'All' # All records after the first must be passive. firstargs = args nextargs = args.copy() nextargs['SCAN'] = 'Passive' if 'PINI' in nextargs: del nextargs['PINI'] def fieldname(i): return 'LNK%d' % (i + 1) def identity(x): return x record_list = _fanout_helper( name, record_list, 6, records.fanout, fieldname, identity, firstargs, nextargs) return record_list[0]
[docs]def create_dfanout(name, *record_list, **args): # All records after the first argument must operate passively and in # supervisory mode as they are simply mirroring the first record. firstargs = args nextargs = args.copy() nextargs.update(dict(SCAN = 'Passive', OMSL = 'supervisory')) if 'DOL' in nextargs: del nextargs['DOL'] if 'PINI' in nextargs: del nextargs['PINI'] def fieldname(i): return 'OUT%c' % (ord('A') + i) record_list = _fanout_helper( name, record_list, 8, records.dfanout, fieldname, PP, firstargs, nextargs) return record_list[0]