Ejemplo n.º 1
0
def _GenerateTypeInfo(type_info, prefix):
  """Generate TypeInfo structures."""
  fields = ''
  for path, field_type in _GetType(type_info.ctype):
    fields += textwrap.dedent("""\
        {{".{prefix}.{path}", kDataType{type}, OFFSET_OF({name}, {path})}},
        """).format(name=type_info.struct_name, prefix=prefix, path=path[1:],
                    type=c_helpers.SnakeToCamel(field_type))

  s = textwrap.dedent("""\
      const TypeInfoField kTypeInfoField{struct_name}[] = {{
      {fields}
      }};

      const TypeInfo kTypeInfo{struct_name} = {{
        reinterpret_cast<PackTypeFunction>({pack_func}), {pack_size},
        reinterpret_cast<UnpackTypeFunction>({unpack_func}), {unpack_size},
        ARRAYSIZE(kTypeInfoField{struct_name}), kTypeInfoField{struct_name}
      }};

      """).format(fields=c_helpers.Indent(fields, 1)[:-1],
                  struct_name=type_info.struct_name,
                  pack_func=type_info.pack_func,
                  pack_size=type_info.pack_size,
                  unpack_func=type_info.unpack_func,
                  unpack_size=type_info.unpack_size)

  return s
Ejemplo n.º 2
0
def _GenerateGetMessageTypeInfo():
  """Generate accessor functions for the message type TypeInfo structures."""
  info_map = aio_message.GetMessageInfoMapByNetworkFile()
  supported_types = {k: v for k, v in info_map.iteritems() if v}
  unsupported_types = [k for k, v in info_map.iteritems() if not v]
  s = textwrap.dedent("""\
      const TypeInfo *GetMessageTypeInfo(MessageType message) {
        switch (message) {
      """)
  for message, info in supported_types.iteritems():
    s += c_helpers.Indent(textwrap.dedent("""\
        case {enum_name}:
          return &kTypeInfo{struct_name};
        """).format(enum_name=message.enum_name,
                    struct_name=info.struct_name), 2)
  for message in unsupported_types:
    s += c_helpers.Indent(textwrap.dedent("""\
        case {enum_name}:
          return nullptr;  // Not supported.
        """).format(enum_name=message.enum_name), 2)
  s += textwrap.dedent("""\
          case kNumMessageTypes:
          default:
            return nullptr;
        }
      }

      """)
  # GCC 6.3, differently than GCC 4.8, treats type-assignments as equal types,
  # so generating functions with equivalent types result in redefinition error.
  # Therefore we have to identify unique types not from names but from the
  # actual type definition.
  unique_types = set()
  for v in supported_types.values():
    struct_name = v.struct_name
    if v.ctype in unique_types:
      continue
    unique_types.add(v.ctype)
    s += textwrap.dedent("""\
        template<> const TypeInfo *GetTypeInfo<{struct_name}>() {{
          return &kTypeInfo{struct_name};
        }}

        """).format(struct_name=struct_name)
  return s
Ejemplo n.º 3
0
def _GenerateHeader(header_file):
  """Generate output header file."""
  guard = re.sub('[/.]', '_', header_file).upper() + '_'
  data_types = sorted(['kDataType' + c_helpers.SnakeToCamel(s)
                       for s in _TYPE_MAP.values()])
  s = textwrap.dedent("""\
      #ifndef {guard}
      #define {guard}

      #include <stddef.h>
      #include <stdint.h>

      #include "avionics/network/message_type.h"

      typedef size_t (*PackTypeFunction)(const void *in,
                                         size_t num,
                                         uint8_t *out);

      typedef size_t (*UnpackTypeFunction)(const uint8_t *in,
                                           size_t num,
                                           void *out);

      typedef enum {{
      {data_types},
        kNumDataTypes
      }} DataType;

      typedef struct {{
        const char *path;
        DataType type;
        size_t offset;
      }} TypeInfoField;

      typedef struct {{
        PackTypeFunction pack;
        size_t pack_size;
        UnpackTypeFunction unpack;
        size_t unpack_size;
        int32_t num_fields;
        const TypeInfoField *field;
      }} TypeInfo;

      template <typename T> const TypeInfo *GetTypeInfo();

      const TypeInfo *GetCaptureHeaderTypeInfo(void);
      const TypeInfo *GetAioHeaderTypeInfo(void);
      const TypeInfo *GetMessageTypeInfo(MessageType message);

      void ConvertDataType(int64_t n, DataType src_type, size_t src_offset,
                           size_t src_step, const void *src, DataType dst_type,
                           size_t dst_offset, size_t dst_step, void *dst);

      #endif  // {guard}
      """).format(guard=guard,
                  data_types=c_helpers.Indent(',\n'.join(data_types)))
  return s
Ejemplo n.º 4
0
 def _LinksToStrings(name, links):
     if links:
         strings = [
             textwrap.dedent("""\
       static const SwitchLinkInfo {name}[] = {{""".format(name=name))
         ]
         entries = ', '.join([_LinkToString(link) for link in links])
         strings += [c_helpers.Indent(entries)]
         strings += ['};\n']
         return strings, name
     return [], 'NULL'
Ejemplo n.º 5
0
    def _GenerateConfigDeviceText(self, path, revision, config_ref_by_text):
        """Helper function for GenerateMapByAddress.

    Args:
      path: A list of pack2 enum names describing the configuration type.
      revision: A dict describing the source code associated with this revision.
      config_ref_by_text: A dict mapping the source code initialization to
                          variable reference. This function updates this map.

    Returns:
      A tuple containing the source code initialization for config and device
      structures.
    """
        # Parts in output.
        config_parts = []
        device_parts = []

        # Generate config structure for each device.
        addresses = revision['text_by_address'].keys()
        for config_index, address in enumerate(addresses):
            num_configs = len(revision['devices_by_address'][address])

            # If config_text exists in config_ref_by_text, do not duplicate.
            config_text = revision['text_by_address'][address]
            if config_text in config_ref_by_text:
                config_ref = config_ref_by_text[config_text]
            else:
                config_ref = 'kConfig{}Address0x{:02X}'.format(
                    self._PathToString(path), address)
                config_ref_by_text[config_text] = config_ref
                config_parts.append(
                    textwrap.dedent("""\
            static const {type_prefix}MonitorConfig {ref}[{num}] = {{
            {text}}};
            """).format(type_prefix=self._type_prefix,
                        ref=config_ref,
                        text=c_helpers.Indent(config_text),
                        num=num_configs))

            # Generate device text using remapped config_ref such to eliminate
            # redundent device structures.
            device_parts.append(
                textwrap.dedent("""\
          [{config_index}] = {{
            .config = {config_ref},
            .num_configs = {num_configs}}},
          """).format(config_index=config_index,
                      config_ref=config_ref,
                      num_configs=num_configs))

        return (config_parts, device_parts)
Ejemplo n.º 6
0
 def _GenerateRevisionMapRecursive(self, path, device_ref_by_path,
                                   revision_key):
     """Generate map recursively for all revision paths."""
     parts = ['{']
     if len(path) == len(self._enum_path):
         revision = self._revision_by_path.get(tuple(path))
         if revision:
             populated = self._GetPopulated(revision)
             device_ref = device_ref_by_path[tuple(path)]
             num_devices = len(revision[revision_key])
             devices = revision['devices']
         else:
             populated = 0
             device_ref = 'NULL'
             num_devices = 0
             devices = []
         if self._get_revision_fields:
             parts.append(
                 c_helpers.Indent(self._get_revision_fields(devices)))
         parts.append(
             c_helpers.Indent(
                 textwrap.dedent("""\
       .populated = 0x{populated:08X},
       .device = {device_ref},
       .num_devices = {num_devices}}}
       """))[:-1].format(populated=populated,
                         device_ref=device_ref,
                         num_devices=num_devices))
     else:
         for name in self._enum_path[len(path)].Names():
             value = self._GenerateRevisionMapRecursive(
                 path + [name], device_ref_by_path, revision_key)
             parts.append('  [{name}] = {value},'.format(
                 name=name.CName(), value=c_helpers.Indent(value)[2:]))
         parts.append('}')
     return '\n'.join(parts)
Ejemplo n.º 7
0
    def _GenerateDeviceReference(self, type_name, path, num_devices,
                                 device_text, device_ref_by_text):
        """Helper function for GenerateMap and GenerateMapByAddress.

    Args:
      type_name: Specify 'Monitor' or 'MonitorDevice'.
      path: A list of pack2 enum names describing the configuration type.
      num_devices: Total number of devices in list.
      device_text: Source code initialization of device corresponding to path.
      device_ref_by_text: A dict mapping the source code initialization to
                          variable reference. This function updates this map.

    Returns:
      A tuple containing the device reference and a list of source code outputs.
    """
        # Parts in output.
        device_parts = []

        # If device_text exists in device_ref_by_text, do not duplicate.
        if device_text in device_ref_by_text:
            device_ref = device_ref_by_text[device_text]
        elif num_devices > 0:
            device_ref = 'kDevice{}'.format(self._PathToString(path))
            device_ref_by_text[device_text] = device_ref
            device_parts.append(
                textwrap.dedent("""\
          static const {type_prefix}{type_name} {device_ref}[{num}] = {{
          {text}}};
          """).format(type_prefix=self._type_prefix,
                      type_name=type_name,
                      device_ref=device_ref,
                      text=c_helpers.Indent(device_text),
                      num=num_devices))
        else:
            device_ref = 'NULL'
            device_ref_by_text[device_text] = device_ref

        return (device_ref, device_parts)
Ejemplo n.º 8
0
def _GenerateParameterTypeInfo(module, name):
  """Generates TypeInfo for members of the 'parameters' group.

  These types are not required for hdf5_to_pcap, so no pack function, pack size,
  or unpack function are required.

  Args:
    module: Module that specifies the Python version of the type.
    name: Name of the type.

  Returns:
    String containing TypeInfo definitions.
  """
  type_info = aio_message.GetInfoByModule(module, name)

  fields = ''
  for path, field_type in _GetType(type_info.ctype):
    fields += textwrap.dedent("""\
        {{".{path}", kDataType{type}, OFFSET_OF({name}, {path})}},
        """).format(name=type_info.struct_name, path=path[1:],
                    type=c_helpers.SnakeToCamel(field_type))

  return textwrap.dedent("""\
      const TypeInfoField kTypeInfoField{struct_name}[] = {{
      {fields}
      }};

      const TypeInfo kTypeInfo{struct_name} = {{
        reinterpret_cast<PackTypeFunction>(NULL), 0,
        reinterpret_cast<UnpackTypeFunction>(NULL), {unpack_size},
        ARRAYSIZE(kTypeInfoField{struct_name}), kTypeInfoField{struct_name}
      }};

      """).format(fields=c_helpers.Indent(fields, 1)[:-1],
                  struct_name=type_info.struct_name,
                  unpack_size=ctypes.sizeof(type_info.ctype))
Ejemplo n.º 9
0
def _GenerateSource(info_map, header_file):
    """Generate output source file as a string."""
    parts = [
        textwrap.dedent("""\
      #include "{header_file}"

      #include <assert.h>
      #include <stdbool.h>
      #include <stddef.h>
      #include <stdint.h>
      """).format(header_file=header_file)
    ]

    includes = aio_message.GetHeaderFilesFromMessageInfoMap(info_map)
    includes += ['avionics/network/message_type.h']
    parts += ['#include "%s"' % f for f in sorted(includes)]

    parts.append(
        '\nconst AioMessageInfo kAioMessageInfo[kNumMessageTypes] = {')
    for message in sorted(info_map.keys(), key=lambda m: m.name):
        info = info_map[message]
        if info:
            parts.append(
                c_helpers.Indent(
                    textwrap.dedent("""\
          [{enum_name}] = {{
            .name = "{enum_name}",
            .short_name = "{short_name}",
            .pack_func = (PackAioMessageFunction){pack_func},
            .unpack_func = (UnpackAioMessageFunction){unpack_func},
            .pack_size = {pack_size},
            .unpack_size = {unpack_size}}},""").format(
                        enum_name=message.enum_name,
                        short_name=message.name,
                        pack_func=info.pack_func,
                        pack_size=info.pack_size,
                        unpack_func=info.unpack_func,
                        unpack_size=info.unpack_size)))
        else:
            parts.append(
                c_helpers.Indent(
                    textwrap.dedent("""\
          [{enum_name}] = {{
            .name = "{enum_name}",
            .short_name = "{short_name}",
            .pack_func = NULL,
            .unpack_func = NULL,
            .pack_size = -1,
            .unpack_size = -1}},""").format(enum_name=message.enum_name,
                                            short_name=message.name)))
    parts.append('};')

    parts.append(
        textwrap.dedent("""
      size_t PackAioMessageData(MessageType type, const void *in,
                                 uint8_t *out) {
        if (type < kNumMessageTypes
            && kAioMessageInfo[type].pack_func != NULL) {
          return kAioMessageInfo[type].pack_func(in, 1, out);
        }
        assert(false);
        return 0;
      }

      size_t UnpackAioMessageData(MessageType type, const uint8_t *in,
                                   void *out) {
        if (type < kNumMessageTypes
            && kAioMessageInfo[type].unpack_func != NULL) {
          return kAioMessageInfo[type].unpack_func(in, 1, out);
        }
        assert(false);
        return 0;
      }
      """))
    return '\n'.join(parts)