Example #1
0
def outputC(specification, options, hFile, cFile):
    """
    Outputs C header file.

    Given the specification construct a valid C header
    file that describes all the binary packets.

    Args:
        specification (dict): The specification object.
        options (dict):       A dictionary of options to
                              modify output.
        hFile (file):         A file-like object to which
                              to save the header.
        cFile (file):         A file-like object to which
                              to save the C code.
    """
    assert isinstance(specification, dict)
    assert hasattr(hFile, 'write')
    assert hasattr(cFile, 'write')
    writeOut(cFile, '/** @file {} */'.format(options['cFilename']))
    writeOut(cFile, '#include "{}"'.format(options['hFilename']))
    defName = "STRUCTSPEC_{}_H".format(specification['id'].upper())
    writeOut(hFile, '/** @file {} */'.format(options['hFilename']))
    writeOut(hFile, '#ifndef {}'.format(defName))
    writeOut(hFile, '#define {}'.format(defName))
    writeOut(hFile, '#ifdef __cplusplus')
    writeOut(hFile, 'extern "C"')
    writeOut(hFile, '{')
    writeOut(hFile, '#endif /* __cplusplus */')
    writeOut(hFile, '')
    writeOut((hFile, cFile), '/**')
    prefix = ' * '
    writeOut((hFile, cFile), '@brief\t{}'.format(specification['title']),
             prefix)
    if 'description' in specification:
        writeOut((hFile, cFile), ' *')
        writeOutBlock((hFile, cFile),
                      '@details\t'.format(specification['description']),
                      prefix)
    for tag in ('version', 'date', 'author'):
        if tag in specification:
            writeOut((hFile, cFile), ' *')
            writeOut((hFile, cFile), '@{}\t{}'.format(tag, specification[tag]),
                     prefix)
    for tag in ('documentation', 'metadata'):
        if tag in specification:
            writeOut((hFile, cFile), ' *')
            writeOut((hFile, cFile), '[{}]({})'.format(tag.title(),
                                                       specification[tag]),
                     prefix)
    writeOut((hFile, cFile), ' */')
    writeOut((hFile, cFile), '')
    writeOut(hFile, '#include <stdint.h>')
    writeOut(hFile, '')
    for enumerationName, enumeration in specification['enums'].items():
        if not enumeration.get('preprocessor', False):
            writeOut(hFile, '/**')
            writeOut(hFile, '@enum\t{}'.format(enumerationName), ' * ')
        else:
            writeOut(hFile, '/*')
        if 'title' in enumeration:
            writeOut(hFile, enumeration['title'], ' * ')
        else:
            writeOut(hFile, enumerationName, ' * ')
        if 'description' in enumeration:
            writeOut(hFile, ' *')
            writeOutBlock(hFile, enumeration['description'], ' * ')
        writeOut(hFile, ' */')
        if enumeration.get('preprocessor', False):
            for optionName, option in enumeration['options'].items():
                line = []
                if 'description' in option:
                    writeOut(hFile, '/**')
                    writeOutBlock(hFile, option['description'], ' * ')
                    writeOut(hFile, ' */')
                line.append('#define ')
                line.append(optionName)
                if 'value' in option:
                    line.append(' {}'.format(option['value']))
                if 'title' in option:
                    line.append(' /** {} */'.format(option['title']))
                writeOut(hFile, ''.join(line))
        else:
            writeOut(hFile, "typedef enum {")
            lastOption = enumeration['options'].keys()[-1]
            for optionName, option in enumeration['options'].items():
                line = []
                if 'description' in option:
                    writeOut(hFile, '  /**')
                    writeOutBlock(hFile, option['description'], '   * ')
                    writeOut(hFile, '   */')
                line.append(optionName)
                if 'value' in option:
                    line.append(' = {}'.format(option['value']))
                if 'title' in option:
                    line.append(' /** {} */'.format(option['title']))
                if optionName != lastOption:
                    line.append(',')
                writeOut(hFile, ''.join(line), '  ')
            writeOut(hFile, "}} {};".format(enumerationName))
        writeOut(hFile, '')
    for packetName, packet in specification['packets'].items():
        writeOut(hFile, "typedef struct {")
        for structureName, structure in packet['structure'].items():
            line = []
            if 'description' in structure:
                writeOut(hFile, '  /**')
                writeOutBlock(hFile, structure['description'], '   * ')
                writeOut(hFile, '   */')
            if structure['type'].startswith('#/'):
                typeName = structure['type'][structure['type'].rfind('/') + 1:]
            else:
                typeName = structure['type']
            line.append(typeName)
            line.append(' ')
            line.append(structureName)
            if 'count' in structure:
                if structure['count'].startswith('#/'):
                    countLabel = structure['count'][:-len(schemaVal)]
                    countLabel = countLabel[countLabel.rfind('/') + 1:]
                else:
                    countLabel = structure['count']
                line.append('[{}]'.format(countLabel))
            if 'size' in structure:
                if structure['size'].startswith('#/'):
                    sizeLabel = structure['size'][:-len(schemaVal)]
                    sizeLabel = sizeLabel[sizeLabel.rfind('/') + 1:]
                    sizeInBits = resolveJsonPointer(specification,
                                                    structure['size'][1:])
                else:
                    sizeLabel = structure['size']
                    try:
                        sizeInBits = int(sizeLabel)
                    except ValueError:
                        sizeInBits = 0
                if sizeInBits != typeSizes.get(typeName, -1):
                    line.append(' : {}'.format(sizeLabel))
            if 'title' in structure:
                line.append(' /** {} */'.format(structure['title']))
            line.append(';')
            writeOut(hFile, ''.join(line), '  ')
        writeOut(hFile, "}} {};".format(packetName))
        writeOut(hFile, '')
    writeOut(hFile, '#ifdef __cplusplus')
    writeOut(hFile, '}')
    writeOut(hFile, '#endif /* __cplusplus */')
    writeOut(hFile, '#endif /* {} */'.format(defName))
Example #2
0
def outputC(specification, options, hFile, cFile):
    """
    Outputs C header file.

    Given the specification construct a valid C header
    file that describes all the binary packets.

    Args:
        specification (dict): The specification object.
        options (dict):       A dictionary of options to
                              modify output.
        hFile (file):         A file-like object to which
                              to save the header.
        cFile (file):         A file-like object to which
                              to save the C code.
    """
    assert isinstance(specification, dict)
    assert hasattr(hFile, 'write')
    assert hasattr(cFile, 'write')
    writeOut(cFile, '/** @file {} */'.format(options['cFilename']))
    writeOut(cFile, '#include "{}"'.format(options['hFilename']))
    defName = "STRUCTSPEC_{}_H".format(specification['id'].upper())
    writeOut(hFile, '/** @file {} */'.format(options['hFilename']))
    writeOut(hFile, '#ifndef {}'.format(defName))
    writeOut(hFile, '#define {}'.format(defName))
    writeOut(hFile, '#ifdef __cplusplus')
    writeOut(hFile, 'extern "C"')
    writeOut(hFile, '{')
    writeOut(hFile, '#endif /* __cplusplus */')
    writeOut(hFile, '')
    writeOut((hFile, cFile), '/**')
    prefix = ' * '
    writeOut((hFile, cFile), '@brief\t{}'.format(specification['title']),
             prefix)
    if 'description' in specification:
        writeOut((hFile, cFile), ' *')
        writeOutBlock((hFile, cFile), '@details\t'.format(
                      specification['description']), prefix)
    for tag in ('version', 'date', 'author'):
        if tag in specification:
            writeOut((hFile, cFile), ' *')
            writeOut((hFile, cFile), '@{}\t{}'.format(tag,
                                                      specification[tag]),
                     prefix)
    for tag in ('documentation', 'metadata'):
        if tag in specification:
            writeOut((hFile, cFile), ' *')
            writeOut((hFile, cFile), '[{}]({})'.format(tag.title(),
                                                       specification[tag]),
                     prefix)
    writeOut((hFile, cFile), ' */')
    writeOut((hFile, cFile), '')
    writeOut(hFile, '#include <stdint.h>')
    writeOut(hFile, '')
    for enumerationName, enumeration in specification['enums'].items():
        if not enumeration.get('preprocessor', False):
            writeOut(hFile, '/**')
            writeOut(hFile, '@enum\t{}'.format(enumerationName), ' * ')
        else:
            writeOut(hFile, '/*')
        if 'title' in enumeration:
            writeOut(hFile, enumeration['title'], ' * ')
        else:
            writeOut(hFile, enumerationName, ' * ')
        if 'description' in enumeration:
            writeOut(hFile, ' *')
            writeOutBlock(hFile, enumeration['description'], ' * ')
        writeOut(hFile, ' */')
        if enumeration.get('preprocessor', False):
            for optionName, option in enumeration['options'].items():
                line = []
                if 'description' in option:
                    writeOut(hFile, '/**')
                    writeOutBlock(hFile, option['description'], ' * ')
                    writeOut(hFile, ' */')
                line.append('#define ')
                line.append(optionName)
                if 'value' in option:
                    line.append(' {}'.format(option['value']))
                if 'title' in option:
                    line.append(' /** {} */'.format(option['title']))
                writeOut(hFile, ''.join(line))
        else:
            writeOut(hFile, "typedef enum {")
            lastOption = enumeration['options'].keys()[-1]
            for optionName, option in enumeration['options'].items():
                line = []
                if 'description' in option:
                    writeOut(hFile, '  /**')
                    writeOutBlock(hFile, option['description'], '   * ')
                    writeOut(hFile, '   */')
                line.append(optionName)
                if 'value' in option:
                    line.append(' = {}'.format(option['value']))
                if 'title' in option:
                    line.append(' /** {} */'.format(option['title']))
                if optionName != lastOption:
                    line.append(',')
                writeOut(hFile, ''.join(line), '  ')
            writeOut(hFile, "}} {};".format(enumerationName))
        writeOut(hFile, '')
    for packetName, packet in specification['packets'].items():
        writeOut(hFile, "typedef struct {")
        for structureName, structure in packet['structure'].items():
            line = []
            if 'description' in structure:
                writeOut(hFile, '  /**')
                writeOutBlock(hFile, structure['description'], '   * ')
                writeOut(hFile, '   */')
            if structure['type'].startswith('#/'):
                typeName = structure['type'][structure['type'].rfind('/') + 1:]
            else:
                typeName = structure['type']
            line.append(typeName)
            line.append(' ')
            line.append(structureName)
            if 'count' in structure:
                if structure['count'].startswith('#/'):
                    countLabel = structure['count'][:-len(schemaVal)]
                    countLabel = countLabel[countLabel.rfind('/') + 1:]
                else:
                    countLabel = structure['count']
                line.append('[{}]'.format(countLabel))
            if 'size' in structure:
                if structure['size'].startswith('#/'):
                    sizeLabel = structure['size'][:-len(schemaVal)]
                    sizeLabel = sizeLabel[sizeLabel.rfind('/') + 1:]
                    sizeInBits = resolveJsonPointer(specification,
                                                    structure['size'][1:])
                else:
                    sizeLabel = structure['size']
                    try:
                        sizeInBits = int(sizeLabel)
                    except ValueError:
                        sizeInBits = 0
                if sizeInBits != typeSizes.get(typeName, -1):
                    line.append(' : {}'.format(sizeLabel))
            if 'title' in structure:
                line.append(' /** {} */'.format(structure['title']))
            line.append(';')
            writeOut(hFile, ''.join(line), '  ')
        writeOut(hFile, "}} {};".format(packetName))
        writeOut(hFile, '')
    writeOut(hFile, '#ifdef __cplusplus')
    writeOut(hFile, '}')
    writeOut(hFile, '#endif /* __cplusplus */')
    writeOut(hFile, '#endif /* {} */'.format(defName))
Example #3
0
def populateWorkLists(packet, specification,
                      structDefList, structAccretions):
    """
    Loads work lists based on packet portion of spec.

    Given the portion of the specification definining a
    packets, the specification itself, and the work lists,
    populate them with the relevant information gleaned
    from the packet definition.

    Args:
        packet (dict):           The definition of the
                                 individual packet being
                                 processed.
        specification (dict):    The specification object.
        structDefList (list):    List of items in the
                                 structure.
        structAccretions (dict): Structure information collected
                                 since last processing time.

    Returns:
        A tuple containing the bitfield count and bitfield
        length.
    """
    assert isinstance(packet, dict)
    assert isinstance(specification, dict)
    assert isinstance(structDefList, list)
    assert isinstance(structAccretions, dict)
    assert isinstance(structAccretions['formatList'], list) and \
        isinstance(structAccretions['countList'], list) and \
        isinstance(structAccretions['varList'], list) and \
        isinstance(structAccretions['bitFields'], list)
    bitFieldCount = bitFieldLen = 0
    for structureName, structure in packet['structure'].items():
        endianness = structure.get('endianness', packet.get('endianness',
                                   specification.get('endianness', ''))).encode('utf-8')
        if structure['type'].startswith('#/'):
            handleStructBreaks(structDefList, structAccretions, endianness)
            typeName = structure['type'][structure['type'].rfind('/') + 1:]
            structDefList.append({
                'type': 'substructure',
                'itemName': structureName,
                'itemType': typeName,
                'description': structure.get('description', None),
                'title': structure.get('title', None)
            })
        else:
            typeName = structure['type']
            if 'count' in structure:
                if structure['count'].startswith('#/'):
                    countLabel = structure['count'][:-len(schemaVal)]
                    countLabel = countLabel[countLabel.rfind('/') + 1:]
                    structAccretions['formatList'].append('{}')
                    structAccretions['countList'].append(countLabel)
                else:
                    countLabel = structure['count']
                    structAccretions['formatList'].append(countLabel)
            gotBitField = False
            if 'size' in structure:
                if structure['size'].startswith('#/'):
                    sizeLabel = structure['size'][:-len(schemaVal)]
                    sizeLabel = sizeLabel[sizeLabel.rfind('/') + 1:]
                    sizeInBits = resolveJsonPointer(specification,
                                                    structure['size'][1:])
                else:
                    sizeLabel = structure['size']
                    try:
                        sizeInBits = int(sizeLabel)
                    except ValueError:
                        sizeInBits = 0
                if sizeInBits != typeSizes.get(typeName, -1) or \
                   sizeInBits % 8 != 0:
                    gotBitField = True
            if typeName in typeFormatChar and not gotBitField:
                bitFieldCount = handleBitFields(bitFieldLen, bitFieldCount,
                                                structAccretions)
                bitFieldLen = 0
                structAccretions['formatList'].append(typeFormatChar[typeName])
                structAccretions['varList'].append(
                    "packet['{}']".format(structureName))
                structAccretions['titles'].append(structure.get('title', None))
                structAccretions['descriptions'].append(structure.get('title', None))
            elif gotBitField:
                bitFieldLen += sizeInBits
                structAccretions['bitFields'].append(
                    ("packet['{}']".format(structureName),
                     bitFieldCount, sizeInBits, typeName))
    bitFieldCount = handleBitFields(bitFieldLen, bitFieldCount,
                                    structAccretions)
    handleStructBreaks(structDefList, structAccretions, endianness)
    return bitFieldCount
Example #4
0
def populateWorkLists(packet, specification, structDefList, structAccretions):
    """
    Loads work lists based on packet portion of spec.

    Given the portion of the specification definining a
    packets, the specification itself, and the work lists,
    populate them with the relevant information gleaned
    from the packet definition.

    Args:
        packet (dict):           The definition of the
                                 individual packet being
                                 processed.
        specification (dict):    The specification object.
        structDefList (list):    List of items in the
                                 structure.
        structAccretions (dict): Structure information collected
                                 since last processing time.

    Returns:
        A tuple containing the bitfield count and bitfield
        length.
    """
    assert isinstance(packet, dict)
    assert isinstance(specification, dict)
    assert isinstance(structDefList, list)
    assert isinstance(structAccretions, dict)
    assert isinstance(structAccretions['formatList'], list) and \
        isinstance(structAccretions['countList'], list) and \
        isinstance(structAccretions['varList'], list) and \
        isinstance(structAccretions['bitFields'], list)
    bitFieldCount = bitFieldLen = 0
    for structureName, structure in packet['structure'].items():
        endianness = structure.get(
            'endianness',
            packet.get('endianness', specification.get('endianness',
                                                       ''))).encode('utf-8')
        if structure['type'].startswith('#/'):
            handleStructBreaks(structDefList, structAccretions, endianness)
            typeName = structure['type'][structure['type'].rfind('/') + 1:]
            structDefList.append({
                'type':
                'substructure',
                'itemName':
                structureName,
                'itemType':
                typeName,
                'description':
                structure.get('description', None),
                'title':
                structure.get('title', None)
            })
        else:
            typeName = structure['type']
            if 'count' in structure:
                if structure['count'].startswith('#/'):
                    countLabel = structure['count'][:-len(schemaVal)]
                    countLabel = countLabel[countLabel.rfind('/') + 1:]
                    structAccretions['formatList'].append('{}')
                    structAccretions['countList'].append(countLabel)
                else:
                    countLabel = structure['count']
                    structAccretions['formatList'].append(countLabel)
            gotBitField = False
            if 'size' in structure:
                if structure['size'].startswith('#/'):
                    sizeLabel = structure['size'][:-len(schemaVal)]
                    sizeLabel = sizeLabel[sizeLabel.rfind('/') + 1:]
                    sizeInBits = resolveJsonPointer(specification,
                                                    structure['size'][1:])
                else:
                    sizeLabel = structure['size']
                    try:
                        sizeInBits = int(sizeLabel)
                    except ValueError:
                        sizeInBits = 0
                if sizeInBits != typeSizes.get(typeName, -1) or \
                   sizeInBits % 8 != 0:
                    gotBitField = True
            if typeName in typeFormatChar and not gotBitField:
                bitFieldCount = handleBitFields(bitFieldLen, bitFieldCount,
                                                structAccretions)
                bitFieldLen = 0
                structAccretions['formatList'].append(typeFormatChar[typeName])
                structAccretions['varList'].append(
                    "packet['{}']".format(structureName))
                structAccretions['titles'].append(structure.get('title', None))
                structAccretions['descriptions'].append(
                    structure.get('title', None))
            elif gotBitField:
                bitFieldLen += sizeInBits
                structAccretions['bitFields'].append(
                    ("packet['{}']".format(structureName), bitFieldCount,
                     sizeInBits, typeName))
    bitFieldCount = handleBitFields(bitFieldLen, bitFieldCount,
                                    structAccretions)
    handleStructBreaks(structDefList, structAccretions, endianness)
    return bitFieldCount