templates don't work inside extern C block on windows

// generated from rosidl_typesupport_coredx_c/resource/msg__type_support_c.cpp.em
// generated code does not contain a copyright notice

@##########################################################################
@# EmPy template for generating <msg>__type_support_c.cpp files for
@#   TOC CoreDX DDS
@#
@# Context:
@#  - spec (rosidl_parser.MessageSpecification)
@#    Parsed specification of the .msg file
@#  - pkg (string)
@#    name of the containing package; equivalent to spec.base_type.pkg_name
@#  - msg (string)
@#    name of the message; equivalent to spec.msg_name
@#  - type (string)
@#    full type of the message; equivalent to spec.base_type.type
@#  - subfolder (string)
@#    The subfolder / subnamespace of the message
@#    Either 'msg' or 'srv'
@#  - get_header_filename_from_msg_name (function)
@##########################################################################
@

#include "@(spec.base_type.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.base_type.type))__rosidl_typesupport_coredx_c.h"

#include <stdio.h>

#include <cassert>
#include <limits>
#include <new>

// Provides the rosidl_typesupport_coredx_c__identifier symbol declaration.
#include "rosidl_typesupport_coredx_c/identifier.h"
// Provides the definition of the message_type_support_callbacks_t struct.
#include "rosidl_typesupport_coredx_cpp/message_type_support.h"

#include "@(pkg)/msg/rosidl_typesupport_coredx_c__visibility_control.h"
@{header_file_name = get_header_filename_from_msg_name(type)}@
#include "@(pkg)/@(subfolder)/@(header_file_name)__struct.h"
#include "@(pkg)/@(subfolder)/@(header_file_name)__functions.h"

#ifndef _WIN32
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
# pragma GCC diagnostic ignored "-Wunused-variable"
# ifdef __clang__
#  pragma clang diagnostic ignored "-Wdeprecated-register"
#  pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
# endif
#endif
#include "@(spec.base_type.pkg_name)/@(subfolder)/dds_coredx/@(spec.base_type.type)_TypeSupport.hh"
#ifndef _WIN32
# pragma GCC diagnostic pop
#endif

// includes and forward declarations of message dependencies and their conversion functions

@# // Include the message header for each non-primitive field.
#if defined(__cplusplus)
extern "C"
{
#endif

@{
includes = {}
for field in spec.fields:
    keys = set([])
    if field.type.is_primitive_type():
        if field.type.is_array:
            keys.add('rosidl_generator_c/primitives_array.h')
            keys.add('rosidl_generator_c/primitives_array_functions.h')
        if field.type.type == 'string':
            keys.add('rosidl_generator_c/string.h')
            keys.add('rosidl_generator_c/string_functions.h')
    else:
        header_file_name = get_header_filename_from_msg_name(field.type.type)
        keys.add('%s/msg/%s__functions.h' % (field.type.pkg_name, header_file_name))
    for key in keys:
        if key not in includes:
            includes[key] = set([])
        includes[key].add(field.name)
}@
@[for key in sorted(includes.keys())]@
#include "@(key)"  // @(', '.join(includes[key]))
@[end for]@

// forward declare type support functions
@{
forward_declares = {}
for field in spec.fields:
    if not field.type.is_primitive_type():
        key = (field.type.pkg_name, field.type.type)
        if key not in includes:
            forward_declares[key] = set([])
        forward_declares[key].add(field.name)
}@
@[for key in sorted(forward_declares.keys())]@
@[  if key[0] != pkg]@
ROSIDL_TYPESUPPORT_COREDX_C_IMPORT_@(pkg)
@[  end if]@
const rosidl_message_type_support_t *
  ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_coredx_c, @(key[0]), msg, @(key[1]))();
@[end for]@

@# // Make callback functions specific to this message type.

@{
__dds_msg_type_prefix = "{0}::{1}::dds_::{2}_".format(
  spec.base_type.pkg_name, subfolder, spec.base_type.type)
}@
using __dds_msg_type = @(__dds_msg_type_prefix);
using __ros_msg_type = @(pkg)__@(subfolder)__@(type);

static bool
register_type(void * untyped_participant, const char * type_name)
{
  if (!untyped_participant) {
    fprintf(stderr, "untyped participant handle is null\n");
    return false;
  }
  if (!type_name) {
    fprintf(stderr, "type name handle is null\n");
    return false;
  }
  DDS::DomainParticipant * participant = static_cast<DDS::DomainParticipant *>(untyped_participant);

  DDS::ReturnCode_t status =
    @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::register_type(participant, type_name);
  switch (status) {
    case DDS::RETCODE_ERROR:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::register_type: "
        "an internal error has occurred\n");
      return false;
    case DDS::RETCODE_BAD_PARAMETER:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::register_type: "
        "bad domain participant or type name parameter\n");
      return false;
    case DDS::RETCODE_OUT_OF_RESOURCES:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::register_type: "
        "out of resources\n");
      return false;
    case DDS::RETCODE_PRECONDITION_NOT_MET:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::register_type: "
        "already registered with a different TypeSupport class\n");
      return false;
    case DDS::RETCODE_OK:
      return true;
    default:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::register_type: unknown return code\n");
  }
  return false;
}

static bool
convert_ros_to_dds(const void * untyped_ros_message, void * untyped_dds_message)
{
  if (!untyped_ros_message) {
    fprintf(stderr, "ros message handle is null\n");
    return false;
  }
  if (!untyped_dds_message) {
    fprintf(stderr, "dds message handle is null\n");
    return false;
  }
  const __ros_msg_type * ros_message = static_cast<const __ros_msg_type *>(untyped_ros_message);
  __dds_msg_type * dds_message = static_cast<__dds_msg_type *>(untyped_dds_message);
@[if not spec.fields]@
  // No fields is a no-op.
  (void)dds_message;
  (void)ros_message;
@[end if]@
@[for field in spec.fields]@
  // Field name: @(field.name)
  {
@[  if not field.type.is_primitive_type()]@
    const message_type_support_callbacks_t * @(field.type.pkg_name)__msg__@(field.type.type)__callbacks =
      static_cast<const message_type_support_callbacks_t *>(
      ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_coredx_c, @(field.type.pkg_name), msg, @(field.type.type)
      )()->data);
@[  end if]@
@[  if field.type.is_array]@
@[    if field.type.array_size and not field.type.is_upper_bound]@
    size_t size = @(field.type.array_size);
@[    else]@
    size_t size = ros_message->@(field.name).size;
    if (size > (std::numeric_limits<int32_t>::max)()) {
      fprintf(stderr, "array size exceeds maximum DDS sequence size\n");
      return false;
    }
@[      if field.type.is_upper_bound]@
    if (size > @(field.type.array_size)) {
      fprintf(stderr, "array size exceeds upper bound\n");
      return false;
    }
@[      end if]@
    uint32_t length = static_cast<int32_t>(size);
    if (!dds_message->@(field.name)_.resize(length)) {
      fprintf(stderr, "failed to set length of sequence\n");
      return false;
    }
@[    end if]@
    for (int32_t i = 0; i < static_cast<int32_t>(size); ++i) {
@[    if field.type.array_size and not field.type.is_upper_bound]@
      auto & ros_i = ros_message->@(field.name)[i];
@[    else]@
      auto & ros_i = ros_message->@(field.name).data[i];
@[    end if]@
@[    if field.type.type == 'string']@
      const rosidl_generator_c__String * str = &ros_i;
      if (str->capacity == 0 || str->capacity <= str->size) {
        fprintf(stderr, "string capacity not greater than size\n");
        return false;
      }
      if (str->data[str->size] != '\0') {
        fprintf(stderr, "string not null-terminated\n");
        return false;
      }
@[      if field.type.string_upper_bound]@
@[        if field.type.array_size and not field.type.is_upper_bound]@
      strncpy(dds_message->@(field.name)_[static_cast<int32_t>(i)], str->data, @(field.type.string_upper_bound)); // array of bounded strings
      dds_message->@(field.name)_[static_cast<int32_t>(i)][static_cast<int32_t>(@(field.type.string_upper_bound))] = '\0';
@[        else]@
      strncpy(dds_message->@(field.name)_[static_cast<int32_t>(i)].value, str->data, @(field.type.string_upper_bound)); // sequence of bounded string
      dds_message->@(field.name)_[static_cast<int32_t>(i)].value[static_cast<int32_t>(@(field.type.string_upper_bound))] = '\0';
@[        end if]@
@[      else]@
      dds_message->@(field.name)_[static_cast<int32_t>(i)] = DDS::String_dup(str->data);
@[      end if]@
@[    elif field.type.type == 'bool']@
      dds_message->@(field.name)_[i] = 1 ? ros_i : 0;
@[    elif field.type.is_primitive_type()]@
      dds_message->@(field.name)_[i] = ros_i;
@[    else]@
      if (!@(field.type.pkg_name)__msg__@(field.type.type)__callbacks->convert_ros_to_dds(
          &ros_i, &dds_message->@(field.name)_[i]))
      {
        return false;
      }
@[    end if]@
    }
@[  elif field.type.type == 'string']@
    const rosidl_generator_c__String * str = &ros_message->@(field.name);
    if (str->capacity == 0 || str->capacity <= str->size) {
      fprintf(stderr, "string capacity not greater than size\n");
      return false;
    }
    if (str->data[str->size] != '\0') {
      fprintf(stderr, "string not null-terminated\n");
      return false;
    }
@[    if field.type.string_upper_bound]@
    strncpy(dds_message->@(field.name)_, str->data, @(field.type.string_upper_bound)); // bounded string
    dds_message->@(field.name)_[static_cast<int32_t>(@(field.type.string_upper_bound))] = '\0';
@[    else]@
    dds_message->@(field.name)_ = DDS::String_dup(str->data);
@[    end if]@
@[  elif field.type.is_primitive_type()]@
    dds_message->@(field.name)_ = ros_message->@(field.name);
@[  else]@
    if (!@(field.type.pkg_name)__msg__@(field.type.type)__callbacks->convert_ros_to_dds(
        &ros_message->@(field.name), &dds_message->@(field.name)_))
    {
      return false;
    }
@[  end if]@
  }

@[end for]@
  return true;
}

static bool
publish(void * dds_data_writer, const void * untyped_ros_message)
{
  if (!dds_data_writer) {
    fprintf(stderr, "data writer handle is null\n");
    return false;
  }
  const __ros_msg_type * ros_message = static_cast<const __ros_msg_type *>(untyped_ros_message);
  if (!ros_message) {
    fprintf(stderr, "ros message handle is null\n");
    return false;
  }

  DDS::DataWriter * topic_writer = static_cast<DDS::DataWriter *>(dds_data_writer);

  __dds_msg_type dds_message;
  if (!convert_ros_to_dds(ros_message, &dds_message)) {
    return false;
  }
  @(pkg)::@(subfolder)::dds_::@(type)_DataWriter * data_writer =
    @(pkg)::@(subfolder)::dds_::@(type)_DataWriter::narrow(topic_writer);
  DDS::ReturnCode_t status = data_writer->write(&dds_message, DDS::HANDLE_NIL);

  switch (status) {
    case DDS::RETCODE_ERROR:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "an internal error has occurred\n");
      return false;
    case DDS::RETCODE_BAD_PARAMETER:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "bad handle or instance_data parameter\n");
      return false;
    case DDS::RETCODE_ALREADY_DELETED:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "this @(__dds_msg_type_prefix)DataWriter has already been deleted\n");
      return false;
    case DDS::RETCODE_OUT_OF_RESOURCES:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "out of resources\n");
      return false;
    case DDS::RETCODE_NOT_ENABLED:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "this @(__dds_msg_type_prefix)DataWriter is not enabled\n");
      return false;
    case DDS::RETCODE_PRECONDITION_NOT_MET:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "the handle has not been registered with this @(__dds_msg_type_prefix)DataWriter\n");
      return false;
    case DDS::RETCODE_TIMEOUT:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "writing resulted in blocking and then exceeded the timeout set by the "
        "max_blocking_time of the ReliabilityQosPolicy\n");
      return false;
    case DDS::RETCODE_OK:
      return true;
    default:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "unknown return code\n");
  }
  return false;
}

static bool
convert_dds_to_ros(const void * untyped_dds_message, void * untyped_ros_message)
{
  if (!untyped_ros_message) {
    fprintf(stderr, "ros message handle is null\n");
    return false;
  }
  if (!untyped_dds_message) {
    fprintf(stderr, "dds message handle is null\n");
    return false;
  }
  const __dds_msg_type * dds_message = static_cast<const __dds_msg_type *>(untyped_dds_message);
  __ros_msg_type * ros_message = static_cast<__ros_msg_type *>(untyped_ros_message);
@[if not spec.fields]@
  // No fields is a no-op.
  (void)dds_message;
  (void)ros_message;
@[end if]@
@[for field in spec.fields]@
  // Field name: @(field.name)
  {
@[  if field.type.is_array]@
@[    if field.type.array_size and not field.type.is_upper_bound]@
    int32_t size = @(field.type.array_size);
@[    else]@
@{
if field.type.type == 'string':
    array_init = 'rosidl_generator_c__String__Array__init'
    array_fini = 'rosidl_generator_c__String__Array__fini'
elif field.type.is_primitive_type():
    array_init = 'rosidl_generator_c__{field.type.type}__Array__init'.format(**locals())
    array_fini = 'rosidl_generator_c__{field.type.type}__Array__fini'.format(**locals())
else:
    array_init = '{field.type.pkg_name}__msg__{field.type.type}__Array__init'.format(**locals())
    array_fini = '{field.type.pkg_name}__msg__{field.type.type}__Array__fini'.format(**locals())
}@
    int32_t size = dds_message->@(field.name)_.length();
    if (ros_message->@(field.name).data) {
      @(array_fini)(&ros_message->@(field.name));
    }
    if (!@(array_init)(&ros_message->@(field.name), size)) {
      return "failed to create array for field '@(field.name)'";
    }
@[    end if]@
    for (int32_t i = 0; i < size; i++) {
@[    if field.type.array_size and not field.type.is_upper_bound]@
      auto & ros_i = ros_message->@(field.name)[i];
@[    else]@
      auto & ros_i = ros_message->@(field.name).data[i];
@[    end if]@
@[    if field.type.type == 'bool']@
      ros_i = (dds_message->@(field.name)_[i] != 0);
@[    elif field.type.type == 'string']@
@[      if field.type.string_upper_bound ]@
@[        if field.type.array_size and not field.type.is_upper_bound]@
  // array of bounded strings
      if (!ros_i.data) {
        rosidl_generator_c__String__init(&ros_i);
      }
      bool succeeded = rosidl_generator_c__String__assign(
        &ros_i,
        dds_message->@(field.name)_[i]);
@[        else]@
  // sequence of bounded strings
      if (!ros_i.data) {
        rosidl_generator_c__String__init(&ros_i);
      }
      bool succeeded = rosidl_generator_c__String__assign(
        &ros_i,
        dds_message->@(field.name)_[i].value);
@[        end if]@
@[      else ]@
      if (!ros_i.data) {
        rosidl_generator_c__String__init(&ros_i);
      }
      bool succeeded = rosidl_generator_c__String__assign(
        &ros_i,
        dds_message->@(field.name)_[i]);
@[      end if]@
      if (!succeeded) {
        fprintf(stderr, "failed to assign string into field '@(field.name)'\n");
        return false;
      }
@[    elif field.type.is_primitive_type()]@
      ros_i = dds_message->@(field.name)_[i];
@[    else]@
      const rosidl_message_type_support_t * ts =
        ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_coredx_c, @(field.type.pkg_name), msg, @(field.type.type))();
      const message_type_support_callbacks_t * callbacks =
        static_cast<const message_type_support_callbacks_t *>(ts->data);
      callbacks->convert_dds_to_ros(&dds_message->@(field.name)_[i], &ros_i);
@[    end if]@
    }
@[  elif field.type.type == 'string']@
    if (!ros_message->@(field.name).data) {
      rosidl_generator_c__String__init(&ros_message->@(field.name));
    }
@[    if field.type.string_upper_bound ]@
    bool succeeded = rosidl_generator_c__String__assign(
      &ros_message->@(field.name),
      &dds_message->@(field.name)_[0]);
@[    else ]@
    bool succeeded = rosidl_generator_c__String__assign(
      &ros_message->@(field.name),
      dds_message->@(field.name)_);
@[    end if]@
    if (!succeeded) {
      fprintf(stderr, "failed to assign string into field '@(field.name)'\n");
      return false;
    }
@[  elif field.type.is_primitive_type()]@
    ros_message->@(field.name) = dds_message->@(field.name)_@(' != 0' if field.type.type == 'bool' else '');
@[  else]@
    const rosidl_message_type_support_t * ts =
      ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_coredx_c, @(field.type.pkg_name), msg, @(field.type.type))();
    const message_type_support_callbacks_t * callbacks =
      static_cast<const message_type_support_callbacks_t *>(ts->data);
    callbacks->convert_dds_to_ros(&dds_message->@(field.name)_, &ros_message->@(field.name));
@[  end if]@
  }

@[end for]@
  return true;
}

static bool
take(
  void * dds_data_reader,
  bool ignore_local_publications,
  void * untyped_ros_message,
  bool * taken,
  void * sending_publication_handle)
{
  if (untyped_ros_message == 0) {
    fprintf(stderr, "invalid ros message pointer\n");
    return false;
  }

  DDS::DataReader * topic_reader = static_cast<DDS::DataReader *>(dds_data_reader);

  @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader * data_reader =
    @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader::narrow(topic_reader);

  @(__dds_msg_type_prefix)PtrSeq dds_messages;
  DDS::SampleInfoSeq sample_infos;
  DDS::ReturnCode_t status = data_reader->take(
    &dds_messages,
    &sample_infos,
    1,
    DDS::ANY_SAMPLE_STATE,
    DDS::ANY_VIEW_STATE,
    DDS::ANY_INSTANCE_STATE);

  bool ignore_sample = false;

  switch (status) {
    case DDS::RETCODE_ERROR:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.take: "
        "an internal error has occurred\n");
      goto finally;
    case DDS::RETCODE_ALREADY_DELETED:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.take: "
        "this @(__dds_msg_type_prefix)DataReader has already been deleted\n");
      goto finally;
    case DDS::RETCODE_OUT_OF_RESOURCES:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.take: "
        "out of resources\n");
      goto finally;
    case DDS::RETCODE_NOT_ENABLED:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.take: "
        "this @(__dds_msg_type_prefix)DataReader is not enabled\n");
      goto finally;
    case DDS::RETCODE_PRECONDITION_NOT_MET:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.take: "
        "a precondition is not met, one of: "
        "max_samples > maximum and max_samples != LENGTH_UNLIMITED, or "
        "the two sequences do not have matching parameters (length, maximum, release), or "
        "maximum > 0 and release is false.\n");
      goto finally;
    case DDS::RETCODE_NO_DATA:
      *taken = false;
      goto finally;
    case DDS::RETCODE_OK:
      break;
    default:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.take: "
        "unknown return code\n");
      goto finally;
  }

  {
    DDS::SampleInfo * sample_info = sample_infos[0];
    if (!sample_info->valid_data) {
      // skip sample without data
      ignore_sample = true;
    } else if (ignore_local_publications) {
      // compare the lower 12 octets of the guids from the sender and this receiver
      // if they are equal the sample has been sent from this process and should be ignored
      void * pub_key = DDS_InstanceHandle_get_key(sample_info->publication_handle);
      void * sub_key = DDS_InstanceHandle_get_key(topic_reader->get_instance_handle());
      if (pub_key && sub_key) {
        if (memcmp(pub_key, sub_key, 12) == 0) { /* belong to same DomainParticipant */
          ignore_sample = true;
        } else {
          ignore_sample = false;
        }
      }
      // This is nullptr when being used with plain rmw_take, so check first.
      if (sending_publication_handle) {
        *static_cast<DDS::InstanceHandle_t *>(sending_publication_handle) =
          sample_info->publication_handle;
      }
    }
  }

  if (!ignore_sample) {
    if (!convert_dds_to_ros(dds_messages[0], untyped_ros_message)) {
      goto finally;
    }
    *taken = true;
  } else {
    *taken = false;
  }

finally:
  // Ensure the loan is returned.
  status = data_reader->return_loan(&dds_messages, &sample_infos);
  switch (status) {
    case DDS::RETCODE_ERROR:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.return_loan: "
        "an internal error has occurred\n");
      return false;
    case DDS::RETCODE_ALREADY_DELETED:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.return_loan: "
        "this @(__dds_msg_type_prefix)DataReader has already been deleted\n");
      return false;
    case DDS::RETCODE_OUT_OF_RESOURCES:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.return_loan: "
        "out of resources\n");
      return false;
    case DDS::RETCODE_NOT_ENABLED:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.return_loan: "
        "this @(__dds_msg_type_prefix)DataReader is not enabled\n");
      return false;
    case DDS::RETCODE_PRECONDITION_NOT_MET:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.return_loan: "
        "a precondition is not met, one of: "
        "the data_values and info_seq do not belong to a single related pair, or "
        "the data_values and info_seq were not obtained from this "
        "@(__dds_msg_type_prefix)DataReader\n");
      return false;
    case DDS::RETCODE_OK:
      return true;
    default:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.return_loan: "
        "unknown return code\n");
  }

  return false;
}

static bool serialize( const void    * untyped_ros_msg,
		       rmw_serialized_message_t *buf )
{
  if (untyped_ros_msg == 0) {
    fprintf(stderr, "serialize: invalid ros message pointer\n");
    return false;
  }
  if ( !buf ) {
    fprintf(stderr, "serialize: invalid buf pointer\n");
    return false;
  }

  const __ros_msg_type * ros_message = static_cast<const __ros_msg_type *>(untyped_ros_msg);
  __dds_msg_type dds_message;

  // ros data -> dds data
  if (!convert_ros_to_dds(ros_message, &dds_message)) {
    return false;
  }

  // call marshal once to get required size
  size_t buf_len = dds_message.marshal_cdr( NULL, 0, 0, 0, 0 );

  // allocate required buffer
  if ( buf_len > buf->buffer_capacity )
    {
      if ( buf->buffer_capacity > 0 )
	buf->allocator.deallocate( buf->buffer, buf->allocator.state );
      buf->buffer = static_cast<char *>(buf->allocator.allocate(buf_len , buf->allocator.state));
      if ( buf->buffer )
	buf->buffer_capacity = buf_len;
    }

  // call marshal again to serialize data
  buf->buffer_length = dds_message.marshal_cdr( (unsigned char*)buf->buffer, (unsigned int)buf->buffer_capacity, 0, 0, 0 );

  return true;
}

static bool deserialize( void * untyped_ros_msg,
			 const rmw_serialized_message_t *buf )
{
  if (untyped_ros_msg == 0) {
    fprintf(stderr, "deserialize: invalid ros message pointer\n");
    return false;
  }
  if ( !buf  ) {
    fprintf(stderr, "deserialize: invalid buf pointer\n");
    return false;
  }

  __dds_msg_type dds_message;

  // call unmarshal
  dds_message.unmarshal_cdr( (unsigned char*)buf->buffer, 0, (unsigned int)buf->buffer_length, 0, 0 );

  if (!convert_dds_to_ros(&dds_message, untyped_ros_msg)) {
    return false;
  }

  return true;
}

static void * alloc_ros_msg( rcutils_allocator_t * allocator )
{
  void * buf = allocator->allocate( sizeof(__ros_msg_type), allocator->state );
  if ( !buf )
    return NULL;
  __ros_msg_type * ros_message = new(buf) __ros_msg_type;
  return ros_message;
}

static void   free_ros_msg( void * ros_msg, rcutils_allocator_t * allocator )
{
  if ( ros_msg )
    {
      __ros_msg_type * ros_message = static_cast<__ros_msg_type *>(ros_msg);
      ros_message->~__ros_msg_type();
      allocator->deallocate( ros_msg, allocator->state );
    }
}

@
@# // Collect the callback functions and provide a function to get the type support struct.

static message_type_support_callbacks_t __callbacks = {
  "@(pkg)",  // package_name
  "@(msg)",  // message_name
  register_type,  // register_type
  publish,  // publish
  take,  // take
  convert_ros_to_dds,  // convert_ros_to_dds
  convert_dds_to_ros,  // convert_dds_to_ros
  serialize,
  deserialize,
  alloc_ros_msg,
  free_ros_msg
};

static rosidl_message_type_support_t __type_support = {
  rosidl_typesupport_coredx_c__identifier,
  &__callbacks,
  get_message_typesupport_handle_function,
};

const rosidl_message_type_support_t *
ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_coredx_c, @(pkg), @(subfolder), @(msg))() {
  return &__type_support;
}

#if defined(__cplusplus)
}
#endif

// generated from rosidl_typesupport_coredx_c/resource/msg__type_support_c.cpp.em
// generated code does not contain a copyright notice

@##########################################################################
@# EmPy template for generating <msg>__type_support_c.cpp files for
@#   TOC CoreDX DDS
@#
@# Context:
@#  - spec (rosidl_parser.MessageSpecification)
@#    Parsed specification of the .msg file
@#  - pkg (string)
@#    name of the containing package; equivalent to spec.base_type.pkg_name
@#  - msg (string)
@#    name of the message; equivalent to spec.msg_name
@#  - type (string)
@#    full type of the message; equivalent to spec.base_type.type
@#  - subfolder (string)
@#    The subfolder / subnamespace of the message
@#    Either 'msg' or 'srv'
@#  - get_header_filename_from_msg_name (function)
@##########################################################################
@

#include "@(spec.base_type.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.base_type.type))__rosidl_typesupport_coredx_c.h"

#include <stdio.h>

#include <cassert>
#include <limits>

// Provides the rosidl_typesupport_coredx_c__identifier symbol declaration.
#include "rosidl_typesupport_coredx_c/identifier.h"
// Provides the definition of the message_type_support_callbacks_t struct.
#include "rosidl_typesupport_coredx_cpp/message_type_support.h"

#include "@(pkg)/msg/rosidl_typesupport_coredx_c__visibility_control.h"
@{header_file_name = get_header_filename_from_msg_name(type)}@
#include "@(pkg)/@(subfolder)/@(header_file_name)__struct.h"
#include "@(pkg)/@(subfolder)/@(header_file_name)__functions.h"

#ifndef _WIN32
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
# pragma GCC diagnostic ignored "-Wunused-variable"
# ifdef __clang__
#  pragma clang diagnostic ignored "-Wdeprecated-register"
#  pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
# endif
#endif
#include "@(spec.base_type.pkg_name)/@(subfolder)/dds_coredx/@(spec.base_type.type)_TypeSupport.hh"
#ifndef _WIN32
# pragma GCC diagnostic pop
#endif

// includes and forward declarations of message dependencies and their conversion functions

@# // Include the message header for each non-primitive field.
#if defined(__cplusplus)
extern "C"
{
#endif

@{
includes = {}
for field in spec.fields:
    keys = set([])
    if field.type.is_primitive_type():
        if field.type.is_array:
            keys.add('rosidl_generator_c/primitives_array.h')
            keys.add('rosidl_generator_c/primitives_array_functions.h')
        if field.type.type == 'string':
            keys.add('rosidl_generator_c/string.h')
            keys.add('rosidl_generator_c/string_functions.h')
    else:
        header_file_name = get_header_filename_from_msg_name(field.type.type)
        keys.add('%s/msg/%s__functions.h' % (field.type.pkg_name, header_file_name))
    for key in keys:
        if key not in includes:
            includes[key] = set([])
        includes[key].add(field.name)
}@
@[for key in sorted(includes.keys())]@
#include "@(key)"  // @(', '.join(includes[key]))
@[end for]@

// forward declare type support functions
@{
forward_declares = {}
for field in spec.fields:
    if not field.type.is_primitive_type():
        key = (field.type.pkg_name, field.type.type)
        if key not in includes:
            forward_declares[key] = set([])
        forward_declares[key].add(field.name)
}@
@[for key in sorted(forward_declares.keys())]@
@[  if key[0] != pkg]@
ROSIDL_TYPESUPPORT_COREDX_C_IMPORT_@(pkg)
@[  end if]@
const rosidl_message_type_support_t *
  ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_coredx_c, @(key[0]), msg, @(key[1]))();
@[end for]@

@# // Make callback functions specific to this message type.

@{
__dds_msg_type_prefix = "{0}::{1}::dds_::{2}_".format(
  spec.base_type.pkg_name, subfolder, spec.base_type.type)
}@
using __dds_msg_type = @(__dds_msg_type_prefix);
using __ros_msg_type = @(pkg)__@(subfolder)__@(type);

static bool
register_type(void * untyped_participant, const char * type_name)
{
  if (!untyped_participant) {
    fprintf(stderr, "untyped participant handle is null\n");
    return false;
  }
  if (!type_name) {
    fprintf(stderr, "type name handle is null\n");
    return false;
  }
  DDS::DomainParticipant * participant = static_cast<DDS::DomainParticipant *>(untyped_participant);

  DDS::ReturnCode_t status =
    @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::register_type(participant, type_name);
  switch (status) {
    case DDS::RETCODE_ERROR:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::register_type: "
        "an internal error has occurred\n");
      return false;
    case DDS::RETCODE_BAD_PARAMETER:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::register_type: "
        "bad domain participant or type name parameter\n");
      return false;
    case DDS::RETCODE_OUT_OF_RESOURCES:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::register_type: "
        "out of resources\n");
      return false;
    case DDS::RETCODE_PRECONDITION_NOT_MET:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::register_type: "
        "already registered with a different TypeSupport class\n");
      return false;
    case DDS::RETCODE_OK:
      return true;
    default:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::register_type: unknown return code\n");
  }
  return false;
}

static bool
convert_ros_to_dds(const void * untyped_ros_message, void * untyped_dds_message)
{
  if (!untyped_ros_message) {
    fprintf(stderr, "ros message handle is null\n");
    return false;
  }
  if (!untyped_dds_message) {
    fprintf(stderr, "dds message handle is null\n");
    return false;
  }
  const __ros_msg_type * ros_message = static_cast<const __ros_msg_type *>(untyped_ros_message);
  __dds_msg_type * dds_message = static_cast<__dds_msg_type *>(untyped_dds_message);
@[if not spec.fields]@
  // No fields is a no-op.
  (void)dds_message;
  (void)ros_message;
@[end if]@
@[for field in spec.fields]@
  // Field name: @(field.name)
  {
@[  if not field.type.is_primitive_type()]@
    const message_type_support_callbacks_t * @(field.type.pkg_name)__msg__@(field.type.type)__callbacks =
      static_cast<const message_type_support_callbacks_t *>(
      ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_coredx_c, @(field.type.pkg_name), msg, @(field.type.type)
      )()->data);
@[  end if]@
@[  if field.type.is_array]@
@[    if field.type.array_size and not field.type.is_upper_bound]@
    size_t size = @(field.type.array_size);
@[    else]@
    size_t size = ros_message->@(field.name).size;
    if (size > (std::numeric_limits<int32_t>::max)()) {
      fprintf(stderr, "array size exceeds maximum DDS sequence size\n");
      return false;
    }
@[      if field.type.is_upper_bound]@
    if (size > @(field.type.array_size)) {
      fprintf(stderr, "array size exceeds upper bound\n");
      return false;
    }
@[      end if]@
    uint32_t length = static_cast<int32_t>(size);
    if (!dds_message->@(field.name)_.resize(length)) {
      fprintf(stderr, "failed to set length of sequence\n");
      return false;
    }
@[    end if]@
    for (int32_t i = 0; i < static_cast<int32_t>(size); ++i) {
@[    if field.type.array_size and not field.type.is_upper_bound]@
      auto & ros_i = ros_message->@(field.name)[i];
@[    else]@
      auto & ros_i = ros_message->@(field.name).data[i];
@[    end if]@
@[    if field.type.type == 'string']@
      const rosidl_generator_c__String * str = &ros_i;
      if (str->capacity == 0 || str->capacity <= str->size) {
        fprintf(stderr, "string capacity not greater than size\n");
        return false;
      }
      if (str->data[str->size] != '\0') {
        fprintf(stderr, "string not null-terminated\n");
        return false;
      }
@[      if field.type.string_upper_bound]@
@[        if field.type.array_size and not field.type.is_upper_bound]@
      strncpy(dds_message->@(field.name)_[static_cast<int32_t>(i)], str->data, @(field.type.string_upper_bound)); // array of bounded strings
      dds_message->@(field.name)_[static_cast<int32_t>(i)][static_cast<int32_t>(@(field.type.string_upper_bound))] = '\0';
@[        else]@
      strncpy(dds_message->@(field.name)_[static_cast<int32_t>(i)].value, str->data, @(field.type.string_upper_bound)); // sequence of bounded string
      dds_message->@(field.name)_[static_cast<int32_t>(i)].value[static_cast<int32_t>(@(field.type.string_upper_bound))] = '\0';
@[        end if]@
@[      else]@
      dds_message->@(field.name)_[static_cast<int32_t>(i)] = DDS::String_dup(str->data);
@[      end if]@
@[    elif field.type.type == 'bool']@
      dds_message->@(field.name)_[i] = 1 ? ros_i : 0;
@[    elif field.type.is_primitive_type()]@
      dds_message->@(field.name)_[i] = ros_i;
@[    else]@
      if (!@(field.type.pkg_name)__msg__@(field.type.type)__callbacks->convert_ros_to_dds(
          &ros_i, &dds_message->@(field.name)_[i]))
      {
        return false;
      }
@[    end if]@
    }
@[  elif field.type.type == 'string']@
    const rosidl_generator_c__String * str = &ros_message->@(field.name);
    if (str->capacity == 0 || str->capacity <= str->size) {
      fprintf(stderr, "string capacity not greater than size\n");
      return false;
    }
    if (str->data[str->size] != '\0') {
      fprintf(stderr, "string not null-terminated\n");
      return false;
    }
@[    if field.type.string_upper_bound]@
    strncpy(dds_message->@(field.name)_, str->data, @(field.type.string_upper_bound)); // bounded string
    dds_message->@(field.name)_[static_cast<int32_t>(@(field.type.string_upper_bound))] = '\0';
@[    else]@
    dds_message->@(field.name)_ = DDS::String_dup(str->data);
@[    end if]@
@[  elif field.type.is_primitive_type()]@
    dds_message->@(field.name)_ = ros_message->@(field.name);
@[  else]@
    if (!@(field.type.pkg_name)__msg__@(field.type.type)__callbacks->convert_ros_to_dds(
        &ros_message->@(field.name), &dds_message->@(field.name)_))
    {
      return false;
    }
@[  end if]@
  }

@[end for]@
  return true;
}

static bool
publish(void * dds_data_writer, const void * untyped_ros_message)
{
  if (!dds_data_writer) {
    fprintf(stderr, "data writer handle is null\n");
    return false;
  }
  const __ros_msg_type * ros_message = static_cast<const __ros_msg_type *>(untyped_ros_message);
  if (!ros_message) {
    fprintf(stderr, "ros message handle is null\n");
    return false;
  }

  DDS::DataWriter * topic_writer = static_cast<DDS::DataWriter *>(dds_data_writer);

  __dds_msg_type dds_message;
  if (!convert_ros_to_dds(ros_message, &dds_message)) {
    return false;
  }
  @(pkg)::@(subfolder)::dds_::@(type)_DataWriter * data_writer =
    @(pkg)::@(subfolder)::dds_::@(type)_DataWriter::narrow(topic_writer);
  DDS::ReturnCode_t status = data_writer->write(&dds_message, DDS::HANDLE_NIL);

  switch (status) {
    case DDS::RETCODE_ERROR:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "an internal error has occurred\n");
      return false;
    case DDS::RETCODE_BAD_PARAMETER:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "bad handle or instance_data parameter\n");
      return false;
    case DDS::RETCODE_ALREADY_DELETED:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "this @(__dds_msg_type_prefix)DataWriter has already been deleted\n");
      return false;
    case DDS::RETCODE_OUT_OF_RESOURCES:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "out of resources\n");
      return false;
    case DDS::RETCODE_NOT_ENABLED:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "this @(__dds_msg_type_prefix)DataWriter is not enabled\n");
      return false;
    case DDS::RETCODE_PRECONDITION_NOT_MET:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "the handle has not been registered with this @(__dds_msg_type_prefix)DataWriter\n");
      return false;
    case DDS::RETCODE_TIMEOUT:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "writing resulted in blocking and then exceeded the timeout set by the "
        "max_blocking_time of the ReliabilityQosPolicy\n");
      return false;
    case DDS::RETCODE_OK:
      return true;
    default:
      fprintf(stderr, "@(pkg)::@(subfolder)::dds_::@(type)_DataWriter.write: "
        "unknown return code\n");
  }
  return false;
}

static bool
convert_dds_to_ros(const void * untyped_dds_message, void * untyped_ros_message)
{
  if (!untyped_ros_message) {
    fprintf(stderr, "ros message handle is null\n");
    return false;
  }
  if (!untyped_dds_message) {
    fprintf(stderr, "dds message handle is null\n");
    return false;
  }
  const __dds_msg_type * dds_message = static_cast<const __dds_msg_type *>(untyped_dds_message);
  __ros_msg_type * ros_message = static_cast<__ros_msg_type *>(untyped_ros_message);
@[if not spec.fields]@
  // No fields is a no-op.
  (void)dds_message;
  (void)ros_message;
@[end if]@
@[for field in spec.fields]@
  // Field name: @(field.name)
  {
@[  if field.type.is_array]@
@[    if field.type.array_size and not field.type.is_upper_bound]@
    int32_t size = @(field.type.array_size);
@[    else]@
@{
if field.type.type == 'string':
    array_init = 'rosidl_generator_c__String__Array__init'
    array_fini = 'rosidl_generator_c__String__Array__fini'
elif field.type.is_primitive_type():
    array_init = 'rosidl_generator_c__{field.type.type}__Array__init'.format(**locals())
    array_fini = 'rosidl_generator_c__{field.type.type}__Array__fini'.format(**locals())
else:
    array_init = '{field.type.pkg_name}__msg__{field.type.type}__Array__init'.format(**locals())
    array_fini = '{field.type.pkg_name}__msg__{field.type.type}__Array__fini'.format(**locals())
}@
    int32_t size = dds_message->@(field.name)_.length();
    if (ros_message->@(field.name).data) {
      @(array_fini)(&ros_message->@(field.name));
    }
    if (!@(array_init)(&ros_message->@(field.name), size)) {
      return "failed to create array for field '@(field.name)'";
    }
@[    end if]@
    for (int32_t i = 0; i < size; i++) {
@[    if field.type.array_size and not field.type.is_upper_bound]@
      auto & ros_i = ros_message->@(field.name)[i];
@[    else]@
      auto & ros_i = ros_message->@(field.name).data[i];
@[    end if]@
@[    if field.type.type == 'bool']@
      ros_i = (dds_message->@(field.name)_[i] != 0);
@[    elif field.type.type == 'string']@
@[      if field.type.string_upper_bound ]@
@[        if field.type.array_size and not field.type.is_upper_bound]@
  // array of bounded strings
      if (!ros_i.data) {
        rosidl_generator_c__String__init(&ros_i);
      }
      bool succeeded = rosidl_generator_c__String__assign(
        &ros_i,
        dds_message->@(field.name)_[i]);
@[        else]@
  // sequence of bounded strings
      if (!ros_i.data) {
        rosidl_generator_c__String__init(&ros_i);
      }
      bool succeeded = rosidl_generator_c__String__assign(
        &ros_i,
        dds_message->@(field.name)_[i].value);
@[        end if]@
@[      else ]@
      if (!ros_i.data) {
        rosidl_generator_c__String__init(&ros_i);
      }
      bool succeeded = rosidl_generator_c__String__assign(
        &ros_i,
        dds_message->@(field.name)_[i]);
@[      end if]@
      if (!succeeded) {
        fprintf(stderr, "failed to assign string into field '@(field.name)'\n");
        return false;
      }
@[    elif field.type.is_primitive_type()]@
      ros_i = dds_message->@(field.name)_[i];
@[    else]@
      const rosidl_message_type_support_t * ts =
        ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_coredx_c, @(field.type.pkg_name), msg, @(field.type.type))();
      const message_type_support_callbacks_t * callbacks =
        static_cast<const message_type_support_callbacks_t *>(ts->data);
      callbacks->convert_dds_to_ros(&dds_message->@(field.name)_[i], &ros_i);
@[    end if]@
    }
@[  elif field.type.type == 'string']@
    if (!ros_message->@(field.name).data) {
      rosidl_generator_c__String__init(&ros_message->@(field.name));
    }
@[    if field.type.string_upper_bound ]@
    bool succeeded = rosidl_generator_c__String__assign(
      &ros_message->@(field.name),
      &dds_message->@(field.name)_[0]);
@[    else ]@
    bool succeeded = rosidl_generator_c__String__assign(
      &ros_message->@(field.name),
      dds_message->@(field.name)_);
@[    end if]@
    if (!succeeded) {
      fprintf(stderr, "failed to assign string into field '@(field.name)'\n");
      return false;
    }
@[  elif field.type.is_primitive_type()]@
    ros_message->@(field.name) = dds_message->@(field.name)_@(' != 0' if field.type.type == 'bool' else '');
@[  else]@
    const rosidl_message_type_support_t * ts =
      ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_coredx_c, @(field.type.pkg_name), msg, @(field.type.type))();
    const message_type_support_callbacks_t * callbacks =
      static_cast<const message_type_support_callbacks_t *>(ts->data);
    callbacks->convert_dds_to_ros(&dds_message->@(field.name)_, &ros_message->@(field.name));
@[  end if]@
  }

@[end for]@
  return true;
}

static bool
take(
  void * dds_data_reader,
  bool ignore_local_publications,
  void * untyped_ros_message,
  bool * taken,
  void * sending_publication_handle)
{
  if (untyped_ros_message == 0) {
    fprintf(stderr, "invalid ros message pointer\n");
    return false;
  }

  DDS::DataReader * topic_reader = static_cast<DDS::DataReader *>(dds_data_reader);

  @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader * data_reader =
    @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader::narrow(topic_reader);

  @(__dds_msg_type_prefix)PtrSeq dds_messages;
  DDS::SampleInfoSeq sample_infos;
  DDS::ReturnCode_t status = data_reader->take(
    &dds_messages,
    &sample_infos,
    1,
    DDS::ANY_SAMPLE_STATE,
    DDS::ANY_VIEW_STATE,
    DDS::ANY_INSTANCE_STATE);

  bool ignore_sample = false;

  switch (status) {
    case DDS::RETCODE_ERROR:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.take: "
        "an internal error has occurred\n");
      goto finally;
    case DDS::RETCODE_ALREADY_DELETED:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.take: "
        "this @(__dds_msg_type_prefix)DataReader has already been deleted\n");
      goto finally;
    case DDS::RETCODE_OUT_OF_RESOURCES:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.take: "
        "out of resources\n");
      goto finally;
    case DDS::RETCODE_NOT_ENABLED:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.take: "
        "this @(__dds_msg_type_prefix)DataReader is not enabled\n");
      goto finally;
    case DDS::RETCODE_PRECONDITION_NOT_MET:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.take: "
        "a precondition is not met, one of: "
        "max_samples > maximum and max_samples != LENGTH_UNLIMITED, or "
        "the two sequences do not have matching parameters (length, maximum, release), or "
        "maximum > 0 and release is false.\n");
      goto finally;
    case DDS::RETCODE_NO_DATA:
      *taken = false;
      goto finally;
    case DDS::RETCODE_OK:
      break;
    default:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.take: "
        "unknown return code\n");
      goto finally;
  }

  {
    DDS::SampleInfo * sample_info = sample_infos[0];
    if (!sample_info->valid_data) {
      // skip sample without data
      ignore_sample = true;
    } else if (ignore_local_publications) {
      // compare the lower 12 octets of the guids from the sender and this receiver
      // if they are equal the sample has been sent from this process and should be ignored
      void * pub_key = DDS_InstanceHandle_get_key(sample_info->publication_handle);
      void * sub_key = DDS_InstanceHandle_get_key(topic_reader->get_instance_handle());
      if (pub_key && sub_key) {
        if (memcmp(pub_key, sub_key, 12) == 0) { /* belong to same DomainParticipant */
          ignore_sample = true;
        } else {
          ignore_sample = false;
        }
      }
      // This is nullptr when being used with plain rmw_take, so check first.
      if (sending_publication_handle) {
        *static_cast<DDS::InstanceHandle_t *>(sending_publication_handle) =
          sample_info->publication_handle;
      }
    }
  }

  if (!ignore_sample) {
    if (!convert_dds_to_ros(dds_messages[0], untyped_ros_message)) {
      goto finally;
    }
    *taken = true;
  } else {
    *taken = false;
  }

finally:
  // Ensure the loan is returned.
  status = data_reader->return_loan(&dds_messages, &sample_infos);
  switch (status) {
    case DDS::RETCODE_ERROR:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.return_loan: "
        "an internal error has occurred\n");
      return false;
    case DDS::RETCODE_ALREADY_DELETED:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.return_loan: "
        "this @(__dds_msg_type_prefix)DataReader has already been deleted\n");
      return false;
    case DDS::RETCODE_OUT_OF_RESOURCES:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.return_loan: "
        "out of resources\n");
      return false;
    case DDS::RETCODE_NOT_ENABLED:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.return_loan: "
        "this @(__dds_msg_type_prefix)DataReader is not enabled\n");
      return false;
    case DDS::RETCODE_PRECONDITION_NOT_MET:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.return_loan: "
        "a precondition is not met, one of: "
        "the data_values and info_seq do not belong to a single related pair, or "
        "the data_values and info_seq were not obtained from this "
        "@(__dds_msg_type_prefix)DataReader\n");
      return false;
    case DDS::RETCODE_OK:
      return true;
    default:
      fprintf(stderr, "@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_DataReader.return_loan: "
        "unknown return code\n");
  }

  return false;
}

static bool serialize( const void    * untyped_ros_msg,
		       rmw_serialized_message_t *buf )
{
  if (untyped_ros_msg == 0) {
    fprintf(stderr, "serialize: invalid ros message pointer\n");
    return false;
  }
  if ( !buf ) {
    fprintf(stderr, "serialize: invalid buf pointer\n");
    return false;
  }

  const __ros_msg_type * ros_message = static_cast<const __ros_msg_type *>(untyped_ros_msg);
  __dds_msg_type dds_message;

  // ros data -> dds data
  if (!convert_ros_to_dds(ros_message, &dds_message)) {
    return false;
  }

  // call marshal once to get required size
  size_t buf_len = dds_message.marshal_cdr( NULL, 0, 0, 0, 0 );

  // allocate required buffer
  if ( buf_len > buf->buffer_capacity )
    {
      if ( buf->buffer_capacity > 0 )
	buf->allocator.deallocate( buf->buffer, buf->allocator.state );
      buf->buffer = static_cast<char *>(buf->allocator.allocate(buf_len , buf->allocator.state));
      if ( buf->buffer )
	buf->buffer_capacity = buf_len;
    }

  // call marshal again to serialize data
  buf->buffer_length = dds_message.marshal_cdr( (unsigned char*)buf->buffer, (unsigned int)buf->buffer_capacity, 0, 0, 0 );

  return true;
}

static bool deserialize( void * untyped_ros_msg,
			 const rmw_serialized_message_t *buf )
{
  if (untyped_ros_msg == 0) {
    fprintf(stderr, "deserialize: invalid ros message pointer\n");
    return false;
  }
  if ( !buf  ) {
    fprintf(stderr, "deserialize: invalid buf pointer\n");
    return false;
  }

  __dds_msg_type dds_message;

  // call unmarshal
  dds_message.unmarshal_cdr( (unsigned char*)buf->buffer, 0, (unsigned int)buf->buffer_length, 0, 0 );

  if (!convert_dds_to_ros(&dds_message, untyped_ros_msg)) {
    return false;
  }

  return true;
}

#include <new>

static void * alloc_ros_msg( rcutils_allocator_t * allocator )
{
  void * buf = allocator->allocate( sizeof(__ros_msg_type), allocator->state );
  if ( !buf )
    return NULL;
  __ros_msg_type * ros_message = new(buf) __ros_msg_type;
  return ros_message;
}

static void   free_ros_msg( void * ros_msg, rcutils_allocator_t * allocator )
{
  if ( ros_msg )
    {
      __ros_msg_type * ros_message = static_cast<__ros_msg_type *>(ros_msg);
      ros_message->~__ros_msg_type();
      allocator->deallocate( ros_msg, allocator->state );
    }
}

@
@# // Collect the callback functions and provide a function to get the type support struct.

static message_type_support_callbacks_t __callbacks = {
  "@(pkg)",  // package_name
  "@(msg)",  // message_name
  register_type,  // register_type
  publish,  // publish
  take,  // take
  convert_ros_to_dds,  // convert_ros_to_dds
  convert_dds_to_ros,  // convert_dds_to_ros
  serialize,
  deserialize,
  alloc_ros_msg,
  free_ros_msg
};

static rosidl_message_type_support_t __type_support = {
  rosidl_typesupport_coredx_c__identifier,
  &__callbacks,
  get_message_typesupport_handle_function,
};

const rosidl_message_type_support_t *
ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_coredx_c, @(pkg), @(subfolder), @(msg))() {
  return &__type_support;
}

#if defined(__cplusplus)
}
#endif


remove old directory structure that was a reference to an unused repo I'm going to archive the repo too. https://github.com/ros-infrastructure/rosindex_containers

<project>
  <actions/>
  <description>Generated at @ESCAPE(now_str) from template '@ESCAPE(template_name)'</description>
  <keepDependencies>false</keepDependencies>
  <properties>
@(SNIPPET(
    'property_log-rotator',
    days_to_keep=365,
    num_to_keep=100,
))@
@[if job_priority is not None]@
@(SNIPPET(
    'property_job-priority',
    priority=job_priority,
))@
@[end if]@
@(SNIPPET(
    'property_rebuild-settings',
))@
@(SNIPPET(
    'property_requeue-job',
))@
@(SNIPPET(
    'property_job-weight',
))@
  </properties>
@[if upload_repository_url is not None]@
@(SNIPPET(
  'scm_git',
   url=upload_repository_url,
   branch_name=upload_repository_branch,
   git_ssh_credential_id=upload_credential_id,
   relative_target_dir='upload_repository',
   refspec=None,
))@
@[else]@
@(SNIPPET(
    'scm_null',
))@
@[end if]@
  <assignedNode>@(node_label)</assignedNode>
  <canRoam>false</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers>
@(SNIPPET(
    'trigger_timer',
    spec='H 3 * * *',
))@
  </triggers>
  <concurrentBuild>false</concurrentBuild>
  <builders>
@(SNIPPET(
    'builder_system-groovy_check-free-disk-space',
))@
@(SNIPPET(
    'builder_shell_docker-info',
))@
@(SNIPPET(
    'builder_check-docker',
    os_name='ubuntu',
    os_code_name='xenial',
    arch='amd64',
))@
@(SNIPPET(
    'builder_shell_clone-ros-buildfarm',
    ros_buildfarm_repository=ros_buildfarm_repository,
    wrapper_scripts=wrapper_scripts,
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
      'rm -fr $WORKSPACE/repositories',
      'mkdir -p $WORKSPACE/repositories',
      'rm -fr $WORKSPACE/docker_generating_docker',
      'mkdir -p $WORKSPACE/docker_generating_docker'
    ])
))@
@(SNIPPET(
    'builder_shell_key-files',
    script_generating_key_files=script_generating_key_files,
))@
@[for doc_repository_url,branch in doc_repositories.items()]@
@{
import os
doc_repository_name = os.path.splitext(os.path.basename(doc_repository_url))[0]

if not branch:
  repo_branch_arg = ''
else:
  repo_branch_arg = '--no-single-branch -b ' + branch
}@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# BEGIN SECTION: Clone %s"' % doc_repository_name,
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/wrapper/git.py clone --depth 1 %s %s $WORKSPACE/repositories/%s' % (doc_repository_url, repo_branch_arg, doc_repository_name),
        'git -C $WORKSPACE/repositories/%s log -n 1' % doc_repository_name,
        'echo "# END SECTION"',
    ]),
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        '# monitor all subprocesses and enforce termination',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/subprocess_reaper.py' +
        ' $$ --cid-file $WORKSPACE/docker_%s.cid >' % doc_repository_name +
        ' $WORKSPACE/docker_generating_docker/docker_%s.log 2>&1 &' % doc_repository_name,
        '# sleep to give python time to startup',
        'sleep 1',
        '',
        'echo "# BEGIN SECTION: Build Dockerfile - %s"' % doc_repository_name,
        'cd $WORKSPACE/repositories/%s' % doc_repository_name,
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/misc/docker_pull_baseimage.py docker/image/Dockerfile',
        'docker build --force-rm -f docker/image/Dockerfile' +
        ' --build-arg user=`whoami` --build-arg uid=`id -u`' +
        ' -t %s .' % doc_repository_name,
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Run Docker - %s"' % doc_repository_name,
        'docker run' +
        ' --rm' +
        ' --net=host' +
        ' --cidfile=$WORKSPACE/docker_%s.cid' % doc_repository_name +
        ' -v $WORKSPACE/repositories/%s:/tmp/doc_repository' % doc_repository_name +
        ' -v $WORKSPACE/upload_repository:/tmp/upload_repository' +
        ' -e REPO=/tmp/doc_repository' +
        ' -e SITE=/tmp/upload_repository' +
        ' %s' % doc_repository_name,
        'echo "# END SECTION"',
    ]),
))@
@[if upload_host is not None]@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'if [ -d "$WORKSPACE/repositories/%s/build/html" ]; then' % doc_repository_name,
        '  echo "# BEGIN SECTION: rsync documentation to server"',
        '  ssh %s@%s "mkdir -p %s"' %
          (upload_user, upload_host, upload_root),
        '  cd $WORKSPACE/repositories/%s/build' % doc_repository_name,
        '  rsync -e ssh --stats -r --delete html/ %s@%s:%s' % \
          (upload_user, upload_host, upload_root),
        '  echo "# END SECTION"',
        'fi',
    ]),
))@
@[end if]@
@[end for]@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# BEGIN SECTION: Clean up to save disk space on agents"',
        '# ensure to have write permission before trying to delete the folder',
        'chmod -R u+w $WORKSPACE/repositories',
        'rm -fr $WORKSPACE/repositories',
        'echo "# END SECTION"',
    ]),
))@
  </builders>
  <publishers>
@(SNIPPET(
    'publisher_mailer',
    recipients=notify_emails,
    dynamic_recipients=[],
    send_to_individuals=False,
))@
@[if upload_repository_url is not None]@
@(SNIPPET(
    'publisher_publish-over-git',
    branch=upload_repository_branch
))@
@[end if]@
  </publishers>
  <buildWrappers>
@[if timeout_minutes is not None]@
@(SNIPPET(
    'build-wrapper_build-timeout',
    timeout_minutes=timeout_minutes,
))@
@[end if]@
@(SNIPPET(
    'build-wrapper_timestamper',
))@
@[if upload_host is not None]@
@(SNIPPET(
    'build-wrapper_ssh-agent',
    credential_ids=[upload_credential_id],
))@
@[end if]@
  </buildWrappers>
</project>

<project>
  <actions/>
  <description>Generated at @ESCAPE(now_str) from template '@ESCAPE(template_name)'</description>
  <keepDependencies>false</keepDependencies>
  <properties>
@(SNIPPET(
    'property_log-rotator',
    days_to_keep=365,
    num_to_keep=100,
))@
@[if job_priority is not None]@
@(SNIPPET(
    'property_job-priority',
    priority=job_priority,
))@
@[end if]@
@(SNIPPET(
    'property_rebuild-settings',
))@
@(SNIPPET(
    'property_requeue-job',
))@
@(SNIPPET(
    'property_job-weight',
))@
  </properties>
@[if upload_repository_url is not None]@
@(SNIPPET(
  'scm_git',
   url=upload_repository_url,
   branch_name=upload_repository_branch,
   git_ssh_credential_id=upload_credential_id,
   relative_target_dir='upload_repository',
   refspec=None,
))@
@[else]@
@(SNIPPET(
    'scm_null',
))@
@[end if]@
  <assignedNode>@(node_label)</assignedNode>
  <canRoam>false</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers>
@(SNIPPET(
    'trigger_timer',
    spec='H 3 * * *',
))@
  </triggers>
  <concurrentBuild>false</concurrentBuild>
  <builders>
@(SNIPPET(
    'builder_system-groovy_check-free-disk-space',
))@
@(SNIPPET(
    'builder_shell_docker-info',
))@
@(SNIPPET(
    'builder_check-docker',
    os_name='ubuntu',
    os_code_name='xenial',
    arch='amd64',
))@
@(SNIPPET(
    'builder_shell_clone-ros-buildfarm',
    ros_buildfarm_repository=ros_buildfarm_repository,
    wrapper_scripts=wrapper_scripts,
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
      'rm -fr $WORKSPACE/repositories',
      'mkdir -p $WORKSPACE/repositories',
      'rm -fr $WORKSPACE/docker_containers',
      'mkdir -p $WORKSPACE/docker_containers',
      'rm -fr $WORKSPACE/docker_generating_docker',
      'mkdir -p $WORKSPACE/docker_generating_docker'
    ])
))@
@(SNIPPET(
    'builder_shell_key-files',
    script_generating_key_files=script_generating_key_files,
))@
@[for doc_repository_url,branch in doc_repositories.items()]@
@{
import os
doc_repository_name = os.path.splitext(os.path.basename(doc_repository_url))[0]

if not branch:
  repo_branch_arg = ''
else:
  repo_branch_arg = '--no-single-branch -b ' + branch
}@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# BEGIN SECTION: Clone %s"' % doc_repository_name,
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/wrapper/git.py clone --depth 1 %s %s $WORKSPACE/repositories/%s' % (doc_repository_url, repo_branch_arg, doc_repository_name),
        'git -C $WORKSPACE/repositories/%s log -n 1' % doc_repository_name,
        'echo "# END SECTION"',
    ]),
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        '# monitor all subprocesses and enforce termination',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/subprocess_reaper.py' +
        ' $$ --cid-file $WORKSPACE/docker_containers/docker_%s.cid >' % doc_repository_name +
        ' $WORKSPACE/docker_generating_docker/docker_%s.log 2>&1 &' % doc_repository_name,
        '# sleep to give python time to startup',
        'sleep 1',
        '',
        'echo "# BEGIN SECTION: Build Dockerfile - %s"' % doc_repository_name,
        'cd $WORKSPACE/repositories/%s' % doc_repository_name,
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/misc/docker_pull_baseimage.py docker/image/Dockerfile',
        'docker build --force-rm -f docker/image/Dockerfile' +
        ' --build-arg user=`whoami` --build-arg uid=`id -u`' +
        ' -t %s .' % doc_repository_name,
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Run Docker - %s"' % doc_repository_name,
        'docker run' +
        ' --rm' +
        ' --net=host' +
        ' --cidfile=$WORKSPACE/docker_containers/docker_%s.cid' % doc_repository_name +
        ' -v $WORKSPACE/repositories/%s:/tmp/doc_repository' % doc_repository_name +
        ' -v $WORKSPACE/upload_repository:/tmp/upload_repository' +
        ' -e REPO=/tmp/doc_repository' +
        ' -e SITE=/tmp/upload_repository' +
        ' %s' % doc_repository_name,
        'echo "# END SECTION"',
    ]),
))@
@[if upload_host is not None]@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'if [ -d "$WORKSPACE/repositories/%s/build/html" ]; then' % doc_repository_name,
        '  echo "# BEGIN SECTION: rsync documentation to server"',
        '  ssh %s@%s "mkdir -p %s"' %
          (upload_user, upload_host, upload_root),
        '  cd $WORKSPACE/repositories/%s/build' % doc_repository_name,
        '  rsync -e ssh --stats -r --delete html/ %s@%s:%s' % \
          (upload_user, upload_host, upload_root),
        '  echo "# END SECTION"',
        'fi',
    ]),
))@
@[end if]@
@[end for]@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# BEGIN SECTION: Clean up to save disk space on agents"',
        '# ensure to have write permission before trying to delete the folder',
        'chmod -R u+w $WORKSPACE/repositories',
        'rm -fr $WORKSPACE/repositories',
        'echo "# END SECTION"',
    ]),
))@
  </builders>
  <publishers>
@(SNIPPET(
    'publisher_mailer',
    recipients=notify_emails,
    dynamic_recipients=[],
    send_to_individuals=False,
))@
@[if upload_repository_url is not None]@
@(SNIPPET(
    'publisher_publish-over-git',
    branch=upload_repository_branch
))@
@[end if]@
  </publishers>
  <buildWrappers>
@[if timeout_minutes is not None]@
@(SNIPPET(
    'build-wrapper_build-timeout',
    timeout_minutes=timeout_minutes,
))@
@[end if]@
@(SNIPPET(
    'build-wrapper_timestamper',
))@
@[if upload_host is not None]@
@(SNIPPET(
    'build-wrapper_ssh-agent',
    credential_ids=[upload_credential_id],
))@
@[end if]@
  </buildWrappers>
</project>


fix missing static analysis issues column (#797)

Signed-off-by: Dirk Thomas <19795c8185177e940eedd30ceb2b716a54a3d5dc@users.noreply.github.com>

<hudson.plugins.view.dashboard.Dashboard plugin="dashboard-view@@2.12">
  <name>@view_name</name>
  <description>Generated at @ESCAPE(now_str) from template '@ESCAPE(template_name)'</description>
  <filterExecutors>false</filterExecutors>
  <filterQueue>@('true' if filter_queue else 'false')</filterQueue>
  <properties class="hudson.model.View$PropertyList"/>
  <jobNames>
    <comparator class="hudson.util.CaseInsensitiveComparator"/>
  </jobNames>
  <jobFilters/>
  <columns>
    <hudson.views.StatusColumn/>
    <hudson.views.WeatherColumn/>
    <hudson.views.JobColumn/>
    <hudson.views.LastSuccessColumn/>
    <hudson.views.LastFailureColumn/>
    <hudson.views.LastDurationColumn/>
    <jenkins.plugins.extracolumns.BuildDescriptionColumn plugin="extra-columns@@1.20">
      <columnWidth>80</columnWidth>
      <forceWidth>true</forceWidth>
    </jenkins.plugins.extracolumns.BuildDescriptionColumn>
    <hudson.views.BuildButtonColumn/>
    <jenkins.plugins.extracolumns.TestResultColumn plugin="extra-columns@@1.20">
      <testResultFormat>1</testResultFormat>
    </jenkins.plugins.extracolumns.TestResultColumn>
    <io.jenkins.plugins.analysis.core.columns.IssuesTotalColumn plugin="warnings-ng@@8.1.0">
      <selectTools>false</selectTools>
      <tools>
        <io.jenkins.plugins.analysis.core.model.ToolSelection>
          <id></id>
        </io.jenkins.plugins.analysis.core.model.ToolSelection>
      </tools>
      <name># Issues</name>
      <labelProviderFactory>
        <jenkins plugin="plugin-util-api@@1.0.2"/>
      </labelProviderFactory>
      <type>TOTAL</type>
    </io.jenkins.plugins.analysis.core.columns.IssuesTotalColumn>
  </columns>
@[if include_regex]@
  <includeRegex>@include_regex</includeRegex>
@[end if]@
  <recurse>false</recurse>
  <useCssStyle>false</useCssStyle>
  <includeStdJobList>false</includeStdJobList>
  <hideJenkinsPanels>false</hideJenkinsPanels>
  <leftPortletWidth>50%</leftPortletWidth>
  <rightPortletWidth>50%</rightPortletWidth>
  <leftPortlets>
    <hudson.plugins.view.dashboard.stats.StatBuilds>
      <id>dashboard_portlet_5357</id>
      <name>Build statistics</name>
    </hudson.plugins.view.dashboard.stats.StatBuilds>
  </leftPortlets>
  <rightPortlets>
    <hudson.plugins.view.dashboard.test.TestTrendChart>
      <id>dashboard_portlet_6555</id>
      <name>Test Trend Chart</name>
      <graphWidth>500</graphWidth>
      <graphHeight>220</graphHeight>
      <dateRange>0</dateRange>
      <dateShift>0</dateShift>
      <displayStatus>ALL</displayStatus>
    </hudson.plugins.view.dashboard.test.TestTrendChart>
  </rightPortlets>
  <topPortlets/>
  <bottomPortlets>
    <hudson.plugins.view.dashboard.core.HudsonStdJobsPortlet>
      <id>dashboard_portlet_14122</id>
      <name>Jenkins jobs list</name>
    </hudson.plugins.view.dashboard.core.HudsonStdJobsPortlet>
  </bottomPortlets>
</hudson.plugins.view.dashboard.Dashboard>

<hudson.plugins.view.dashboard.Dashboard plugin="dashboard-view@@2.12">
  <name>@view_name</name>
  <description>Generated at @ESCAPE(now_str) from template '@ESCAPE(template_name)'</description>
  <filterExecutors>false</filterExecutors>
  <filterQueue>@('true' if filter_queue else 'false')</filterQueue>
  <properties class="hudson.model.View$PropertyList"/>
  <jobNames>
    <comparator class="hudson.util.CaseInsensitiveComparator"/>
  </jobNames>
  <jobFilters/>
  <columns>
    <hudson.views.StatusColumn/>
    <hudson.views.WeatherColumn/>
    <hudson.views.JobColumn/>
    <hudson.views.LastSuccessColumn/>
    <hudson.views.LastFailureColumn/>
    <hudson.views.LastDurationColumn/>
    <jenkins.plugins.extracolumns.BuildDescriptionColumn plugin="extra-columns@@1.20">
      <columnWidth>80</columnWidth>
      <forceWidth>true</forceWidth>
    </jenkins.plugins.extracolumns.BuildDescriptionColumn>
    <hudson.views.BuildButtonColumn/>
    <jenkins.plugins.extracolumns.TestResultColumn plugin="extra-columns@@1.20">
      <testResultFormat>1</testResultFormat>
    </jenkins.plugins.extracolumns.TestResultColumn>
    <hudson.plugins.warnings.WarningsColumn plugin="warnings@@4.68"/>
  </columns>
@[if include_regex]@
  <includeRegex>@include_regex</includeRegex>
@[end if]@
  <recurse>false</recurse>
  <useCssStyle>false</useCssStyle>
  <includeStdJobList>false</includeStdJobList>
  <hideJenkinsPanels>false</hideJenkinsPanels>
  <leftPortletWidth>50%</leftPortletWidth>
  <rightPortletWidth>50%</rightPortletWidth>
  <leftPortlets>
    <hudson.plugins.view.dashboard.stats.StatBuilds>
      <id>dashboard_portlet_5357</id>
      <name>Build statistics</name>
    </hudson.plugins.view.dashboard.stats.StatBuilds>
  </leftPortlets>
  <rightPortlets>
    <hudson.plugins.view.dashboard.test.TestTrendChart>
      <id>dashboard_portlet_6555</id>
      <name>Test Trend Chart</name>
      <graphWidth>500</graphWidth>
      <graphHeight>220</graphHeight>
      <dateRange>0</dateRange>
      <dateShift>0</dateShift>
      <displayStatus>ALL</displayStatus>
    </hudson.plugins.view.dashboard.test.TestTrendChart>
  </rightPortlets>
  <topPortlets/>
  <bottomPortlets>
    <hudson.plugins.view.dashboard.core.HudsonStdJobsPortlet>
      <id>dashboard_portlet_14122</id>
      <name>Jenkins jobs list</name>
    </hudson.plugins.view.dashboard.core.HudsonStdJobsPortlet>
  </bottomPortlets>
</hudson.plugins.view.dashboard.Dashboard>


Use package manager configuration in mock config (#810)

...instead of assuming either DNF or YUM.

include('/etc/mock/default.cfg')

# Change the root name since we're modifying the chroot
config_opts['root'] += '-ros-buildfarm'

# Disable mock bootstrapping
config_opts['use_bootstrap'] = False

# Add python3-rpm-macros to resolve %{python3_pkgversion} in rosdep rules
config_opts['chroot_setup_cmd'] += ' python3-rpm-macros'

# Install weak dependencies to get group members
config_opts[f'{config_opts.package_manager}_builddep_opts'] = config_opts.get(f'{config_opts.package_manager}_builddep_opts', []) + ['--setopt=install_weak_deps=True']

@[if env_vars]@
# Set environment vars from the build config
@[for env_key, env_val in env_vars.items()]@
config_opts['environment']['@env_key'] = '@env_val'
@[end for]
@[end if]@
# Disable debug packages until infrastructure can handle it
config_opts['macros']['debug_package'] = '%{nil}'

# Hack the %{dist} macro to allow release suffixing
config_opts['macros']['%dist'] = '.' + config_opts['dist'] + '%{?dist_suffix}'

# Required for running mock in Docker
config_opts['use_nspawn'] = False

@[if os_name in ['centos', 'rhel'] and os_code_name == '7']@
# Inject g++ 8 into RHEL 7 builds
config_opts['chroot_setup_cmd'] += ' devtoolset-8-gcc-c++ devtoolset-8-make-nonblocking'
config_opts['macros']['_buildshell'] = '/usr/bin/scl enable devtoolset-8 -- /bin/sh'

# Disable weak dependencies on RHEL 7 builds
config_opts['macros']['_without_weak_deps'] = '1'
@[else]@
# Add g++, which is an assumed dependency in ROS
config_opts['chroot_setup_cmd'] += ' gcc-c++ make'
@[end if]@

config_opts[f'{config_opts.package_manager}.conf'] += """
@[for i, url in enumerate(distribution_repository_urls)]@
[ros-buildfarm-@(i)]
name=ROS Buildfarm Repository @(i) - $basearch
baseurl=@(url)
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ros-buildfarm-@(i)
repo_gpgcheck=@(1 if i < len(distribution_repository_keys) and distribution_repository_keys[i] else 0)
gpgcheck=0
enabled=1
skip_if_unavailable=False

@[end for]@
@[if target_repository]@
[ros-buildfarm-target-source]
name=ROS Buildfarm Repository Target - SRPMS
baseurl=@(target_repository)
repo_gpgcheck=0
gpgcheck=0
enabled=0
skip_if_unavailable=False

@[end if]@
"""

include('/etc/mock/default.cfg')

# Change the root name since we're modifying the chroot
config_opts['root'] += '-ros-buildfarm'

# Disable mock bootstrapping
config_opts['use_bootstrap'] = False

# Add python3-rpm-macros to resolve %{python3_pkgversion} in rosdep rules
config_opts['chroot_setup_cmd'] += ' python3-rpm-macros'

# Install weak dependencies to get group members
config_opts['yum_builddep_opts'] = config_opts.get('yum_builddep_opts', []) + ['--setopt=install_weak_deps=True']
config_opts['dnf_builddep_opts'] = config_opts.get('dnf_builddep_opts', []) + ['--setopt=install_weak_deps=True']
config_opts['microdnf_builddep_opts'] = config_opts.get('microdnf_builddep_opts', []) + ['--setopt=install_weak_deps=True']

@[if env_vars]@
# Set environment vars from the build config
@[for env_key, env_val in env_vars.items()]@
config_opts['environment']['@env_key'] = '@env_val'
@[end for]
@[end if]@
# Disable debug packages until infrastructure can handle it
config_opts['macros']['debug_package'] = '%{nil}'

# Hack the %{dist} macro to allow release suffixing
config_opts['macros']['%dist'] = '.' + config_opts['dist'] + '%{?dist_suffix}'

# Required for running mock in Docker
config_opts['use_nspawn'] = False

@[if os_name in ['centos', 'rhel'] and os_code_name == '7']@
# Inject g++ 8 into RHEL 7 builds
config_opts['chroot_setup_cmd'] += ' devtoolset-8-gcc-c++ devtoolset-8-make-nonblocking'
config_opts['macros']['_buildshell'] = '/usr/bin/scl enable devtoolset-8 -- /bin/sh'

# Disable weak dependencies on RHEL 7 builds
config_opts['macros']['_without_weak_deps'] = '1'
@[else]@
# Add g++, which is an assumed dependency in ROS
config_opts['chroot_setup_cmd'] += ' gcc-c++ make'
@[end if]@

config_opts['yum.conf'] += """
@[for i, url in enumerate(distribution_repository_urls)]@
[ros-buildfarm-@(i)]
name=ROS Buildfarm Repository @(i) - $basearch
baseurl=@(url)
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ros-buildfarm-@(i)
repo_gpgcheck=@(1 if i < len(distribution_repository_keys) and distribution_repository_keys[i] else 0)
gpgcheck=0
enabled=1
skip_if_unavailable=False

@[end for]@
@[if target_repository]@
[ros-buildfarm-target-source]
name=ROS Buildfarm Repository Target - SRPMS
baseurl=@(target_repository)
repo_gpgcheck=0
gpgcheck=0
enabled=0
skip_if_unavailable=False

@[end if]@
"""


using script var (makes expanded template more readable)

#!/usr/bin/env sh
# generated from catkin/cmake/em/setup.sh.em

# Sets various the enviroment variables and sources additional enviroment hooks.
# The output depends on the CMAKE_PREFIX_PATH and the path of this workspace.
# It tries it's best to undo changes from a previously sourced setup file before.
# Supported command line options:
# --extend: skips the undoing of changes from a previously sourced setup file
# Supported enviroment variables:
# _CATKIN_SETUP_NO_RECURSION: skips it's own recursion (when invoked by another setup file)

# environment at generation time
# CURRENT_CMAKE_PREFIX_PATH="@CMAKE_PREFIX_PATH"
# CURRENT_WORKSPACE="@SETUP_DIR"

# remember type of shell if not already set
if [ -z "$CATKIN_SHELL" ]; then
  CATKIN_SHELL=sh
fi

# decide which commands to perform
DO_CLEAN=1
IS_RECURSIVE=0
if [ "$_CATKIN_SETUP_NO_RECURSION" = "1" ]; then
  DO_CLEAN=0
  IS_RECURSIVE=1
elif [ $# -eq 1 -a "$1" = "--extend" ]; then
  DO_CLEAN=0
fi

# folder of workspace prepended to CMAKE_PREFIX_PATH
CMAKE_PREFIX_PATH_dir=""
# include folder of workspace prepended to CPATH
CPATH_dir=/include
# lib folder of workspace prepended to (DY)LD_LIBRARY_PATH
LD_LIBRARY_PATH_dir=/@CATKIN_GLOBAL_LIB_DESTINATION
# bin folder of workspace prepended to PATH
PATH_dir=/@CATKIN_GLOBAL_BIN_DESTINATION
# lib/pkgconfig folder of workspace prepended to PKG_CONFIG_PATH
PKG_CONFIG_PATH_dir=/lib/pkgconfig
# lib/pythonX.Y/..-packages folder of workspace prepended to PYTHONPATH
# the path suffix is calculated in catkin/cmake/python.cmake
PYTHONPATH_dir=/@PYTHON_INSTALL_DIR

# detect if running on Darwin platform
UNAME=`which uname`
UNAME=`$UNAME`
IS_DARWIN=0
if [ "$UNAME" = "Darwin" ]; then
  IS_DARWIN=1
fi

SETUP_UTIL=@SETUP_DIR/_setup_util.py

if [ ! -f "$SETUP_UTIL" ]; then
  echo "Bug: missing util script $SETUP_UTIL"
  return 22
fi

# reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH
# this does not cover modifications performed by environment hooks
if [ $DO_CLEAN -eq 1 ]; then
  export CPATH="$("$SETUP_UTIL" --remove --name CPATH --value "$CPATH_dir")"
  if [ $IS_DARWIN -eq 0 ]; then
    export LD_LIBRARY_PATH="$("$SETUP_UTIL" --remove --name LD_LIBRARY_PATH --value "$LD_LIBRARY_PATH_dir")"
  else
    export DYLD_LIBRARY_PATH="$("$SETUP_UTIL" --remove --name DYLD_LIBRARY_PATH --value "$LD_LIBRARY_PATH_dir")"
  fi
  export PATH="$("$SETUP_UTIL" --remove --name PATH --value "$PATH_dir")"
  export PKG_CONFIG_PATH="$("$SETUP_UTIL" --remove --name PKG_CONFIG_PATH --value "$PKG_CONFIG_PATH_dir")"
  export PYTHONPATH="$("$SETUP_UTIL" --remove --name PYTHONPATH --value "$PYTHONPATH_dir")"
  # rollback CMAKE_PREFIX_PATH last since the other rollback calls rely on this
  export CMAKE_PREFIX_PATH="$("$SETUP_UTIL" --remove --name CMAKE_PREFIX_PATH --value "$CMAKE_PREFIX_PATH_dir")"
fi

# prepend CURRENT_WORKSPACE and CURRENT_CMAKE_PREFIX_PATH to CMAKE_PREFIX_PATH
# the complete list must be set so that environment hooks in parent workspace have the full set available
if [ $IS_RECURSIVE -eq 0 ]; then
  export CMAKE_PREFIX_PATH="$("$SETUP_UTIL" --prefix --name CMAKE_PREFIX_PATH --value "@SETUP_DIR:@CMAKE_PREFIX_PATH")$CMAKE_PREFIX_PATH"
fi

# source setup.SHELL from parent workspaces
if [ $IS_RECURSIVE -eq 0 ]; then
  _CATKIN_SETUP_NO_RECURSION=1
  for workspace in $("$SETUP_UTIL" --get-reversed-workspaces --value "@SETUP_DIR"); do
    . "$workspace/setup.$CATKIN_SHELL"
  done
  _CATKIN_SETUP_NO_RECURSION=0
fi

# prepend folders of workspace to environment variables
export CPATH="$("$SETUP_UTIL" --prefix --name CPATH --value "@SETUP_DIR$CPATH_dir")$CPATH"
if [ $IS_DARWIN -eq 0 ]; then
  export LD_LIBRARY_PATH="$("$SETUP_UTIL" --prefix --name LD_LIBRARY_PATH --value "@SETUP_DIR$LD_LIBRARY_PATH_dir")$LD_LIBRARY_PATH"
else
  export DYLD_LIBRARY_PATH="$("$SETUP_UTIL" --prefix --name DYLD_LIBRARY_PATH --value "@SETUP_DIR$LD_LIBRARY_PATH_dir")$DYLD_LIBRARY_PATH"
fi
export PATH="$("$SETUP_UTIL" --prefix --name PATH --value "@SETUP_DIR$PATH_dir")$PATH"
export PKG_CONFIG_PATH="$("$SETUP_UTIL" --prefix --name PKG_CONFIG_PATH --value "@SETUP_DIR$PKG_CONFIG_PATH_dir")$PKG_CONFIG_PATH"
export PYTHONPATH="$("$SETUP_UTIL" --prefix --name PYTHONPATH --value "@SETUP_DIR$PYTHONPATH_dir")$PYTHONPATH"

# run all environment hooks of this workspace
FIND=`which find`
SORT=`which sort`
ENV_HOOKS_GENERIC=$($FIND "@SETUP_DIR/etc/catkin/profile.d" -maxdepth 1 -name "*.sh" 2>/dev/null | $SORT)
if [ "$CATKIN_SHELL" != "sh" ]; then
  ENV_HOOKS_SPECIFIC=$($FIND "@SETUP_DIR/etc/catkin/profile.d" -maxdepth 1 -name "*.$CATKIN_SHELL" 2>/dev/null | $SORT)
else
  ENV_HOOKS_SPECIFIC=
fi
for envfile in $ENV_HOOKS_GENERIC $ENV_HOOKS_SPECIFIC; do
  . "$envfile"
done

#!/usr/bin/env sh
# generated from catkin/cmake/em/setup.sh.em

# Sets various the enviroment variables and sources additional enviroment hooks.
# The output depends on the CMAKE_PREFIX_PATH and the path of this workspace.
# It tries it's best to undo changes from a previously sourced setup file before.
# Supported command line options:
# --extend: skips the undoing of changes from a previously sourced setup file
# Supported enviroment variables:
# _CATKIN_SETUP_NO_RECURSION: skips it's own recursion (when invoked by another setup file)

# environment at generation time
# CURRENT_CMAKE_PREFIX_PATH="@CMAKE_PREFIX_PATH"
# CURRENT_WORKSPACE="@SETUP_DIR"

# remember type of shell if not already set
if [ -z "$CATKIN_SHELL" ]; then
  CATKIN_SHELL=sh
fi

# decide which commands to perform
DO_CLEAN=1
IS_RECURSIVE=0
if [ "$_CATKIN_SETUP_NO_RECURSION" = "1" ]; then
  DO_CLEAN=0
  IS_RECURSIVE=1
elif [ $# -eq 1 -a "$1" = "--extend" ]; then
  DO_CLEAN=0
fi

# folder of workspace prepended to CMAKE_PREFIX_PATH
CMAKE_PREFIX_PATH_dir=""
# include folder of workspace prepended to CPATH
CPATH_dir=/include
# lib folder of workspace prepended to (DY)LD_LIBRARY_PATH
LD_LIBRARY_PATH_dir=/@CATKIN_GLOBAL_LIB_DESTINATION
# bin folder of workspace prepended to PATH
PATH_dir=/@CATKIN_GLOBAL_BIN_DESTINATION
# lib/pkgconfig folder of workspace prepended to PKG_CONFIG_PATH
PKG_CONFIG_PATH_dir=/lib/pkgconfig
# lib/pythonX.Y/..-packages folder of workspace prepended to PYTHONPATH
# the path suffix is calculated in catkin/cmake/python.cmake
PYTHONPATH_dir=/@PYTHON_INSTALL_DIR

# detect if running on Darwin platform
UNAME=`which uname`
UNAME=`$UNAME`
IS_DARWIN=0
if [ "$UNAME" = "Darwin" ]; then
  IS_DARWIN=1
fi

SETUP_UTIL=@SETUP_DIR/_setup_util.py

if [ ! -f "$SETUP_UTIL" ]; then
  echo "Bug: missing util script $SETUP_UTIL"
  return 22
fi

# reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH
# this does not cover modifications performed by environment hooks
if [ $DO_CLEAN -eq 1 ]; then
  export CPATH="$("@SETUP_DIR/_setup_util.py" --remove --name CPATH --value "$CPATH_dir")"
  if [ $IS_DARWIN -eq 0 ]; then
    export LD_LIBRARY_PATH="$("@SETUP_DIR/_setup_util.py" --remove --name LD_LIBRARY_PATH --value "$LD_LIBRARY_PATH_dir")"
  else
    export DYLD_LIBRARY_PATH="$("@SETUP_DIR/_setup_util.py" --remove --name DYLD_LIBRARY_PATH --value "$LD_LIBRARY_PATH_dir")"
  fi
  export PATH="$("@SETUP_DIR/_setup_util.py" --remove --name PATH --value "$PATH_dir")"
  export PKG_CONFIG_PATH="$("@SETUP_DIR/_setup_util.py" --remove --name PKG_CONFIG_PATH --value "$PKG_CONFIG_PATH_dir")"
  export PYTHONPATH="$("@SETUP_DIR/_setup_util.py" --remove --name PYTHONPATH --value "$PYTHONPATH_dir")"
  # rollback CMAKE_PREFIX_PATH last since the other rollback calls rely on this
  export CMAKE_PREFIX_PATH="$("@SETUP_DIR/_setup_util.py" --remove --name CMAKE_PREFIX_PATH --value "$CMAKE_PREFIX_PATH_dir")"
fi

# prepend CURRENT_WORKSPACE and CURRENT_CMAKE_PREFIX_PATH to CMAKE_PREFIX_PATH
# the complete list must be set so that environment hooks in parent workspace have the full set available
if [ $IS_RECURSIVE -eq 0 ]; then
  export CMAKE_PREFIX_PATH="$("@SETUP_DIR/_setup_util.py" --prefix --name CMAKE_PREFIX_PATH --value "@SETUP_DIR:@CMAKE_PREFIX_PATH")$CMAKE_PREFIX_PATH"
fi

# source setup.SHELL from parent workspaces
if [ $IS_RECURSIVE -eq 0 ]; then
  _CATKIN_SETUP_NO_RECURSION=1
  for workspace in $("@SETUP_DIR/_setup_util.py" --get-reversed-workspaces --value "@SETUP_DIR"); do
    . "$workspace/setup.$CATKIN_SHELL"
  done
  _CATKIN_SETUP_NO_RECURSION=0
fi

# prepend folders of workspace to environment variables
export CPATH="$("@SETUP_DIR/_setup_util.py" --prefix --name CPATH --value "@SETUP_DIR$CPATH_dir")$CPATH"
if [ $IS_DARWIN -eq 0 ]; then
  export LD_LIBRARY_PATH="$("@SETUP_DIR/_setup_util.py" --prefix --name LD_LIBRARY_PATH --value "@SETUP_DIR$LD_LIBRARY_PATH_dir")$LD_LIBRARY_PATH"
else
  export DYLD_LIBRARY_PATH="$("@SETUP_DIR/_setup_util.py" --prefix --name DYLD_LIBRARY_PATH --value "@SETUP_DIR$LD_LIBRARY_PATH_dir")$DYLD_LIBRARY_PATH"
fi
export PATH="$("@SETUP_DIR/_setup_util.py" --prefix --name PATH --value "@SETUP_DIR$PATH_dir")$PATH"
export PKG_CONFIG_PATH="$("@SETUP_DIR/_setup_util.py" --prefix --name PKG_CONFIG_PATH --value "@SETUP_DIR$PKG_CONFIG_PATH_dir")$PKG_CONFIG_PATH"
export PYTHONPATH="$("@SETUP_DIR/_setup_util.py" --prefix --name PYTHONPATH --value "@SETUP_DIR$PYTHONPATH_dir")$PYTHONPATH"

# run all environment hooks of this workspace
FIND=`which find`
SORT=`which sort`
ENV_HOOKS_GENERIC=$($FIND "@SETUP_DIR/etc/catkin/profile.d" -maxdepth 1 -name "*.sh" 2>/dev/null | $SORT)
if [ "$CATKIN_SHELL" != "sh" ]; then
  ENV_HOOKS_SPECIFIC=$($FIND "@SETUP_DIR/etc/catkin/profile.d" -maxdepth 1 -name "*.$CATKIN_SHELL" 2>/dev/null | $SORT)
else
  ENV_HOOKS_SPECIFIC=
fi
for envfile in $ENV_HOOKS_GENERIC $ENV_HOOKS_SPECIFIC; do
  . "$envfile"
done