Convert-Binary-C

 view release on metacpan or  search on metacpan

bin/ccconfig  view on Meta::CPAN


  if ($self->{'inc-path'}) {
    for (@{$self->{'inc-path'}}) {
      $_ .= _OS('file-sep') unless /[:\/\\]$/
    }
  }
  elsif ($self->{can_read_ppout}) {
    $self->{'inc-path'} = $self->_run_incpath;
  }
  else {
    $self->{'inc-path'} = [];
  }

  ($self->{names}, $asserts)  = $self->_names( $self->{'inc-path'} );

  if ($self->{can_preprocess}) {
    $self->{predefined}         = $self->_get_predefined( $self->{names} );
    $self->{preasserted}        = $self->_get_preasserted( $asserts );
    $self->{stdc_version}       = delete $self->{predefined}{__STDC_VERSION__};
    $self->{stdc_hosted}        = delete $self->{predefined}{__STDC_HOSTED__};

    $self->{stdc_version} =~ s/L$// if defined $self->{stdc_version};
  }

  if ($self->{can_compile} || $self->{can_run}) {
    $self->{invalid_keywords}   = $self->_get_invalid_keywords;
    $self->{keyword_map}        = $self->_get_keyword_map;
    $self->{cpp_comments}       = $self->_get_cpp_comments;

    $self->{basic_sizes}        = $self->_get_basic_sizes;
    $self->{byteorder}          = $self->_get_byteorder;
    $self->{unsigned_chars}     = $self->_get_unsigned_chars;
    $self->{alignment}          = $self->_get_alignment;
    $self->{compound_alignment} = $self->_get_compound_alignment;

    # run _after_ byteorder test
    $self->{float_format}       = $self->_get_float_format;
  }
}

sub _compiler
{
  my $self = shift;

  exists $self->{predefined}{__clang__}        and return CLANG;

  exists $self->{predefined}{__GNUC__}         and return GNU_GCC;

  exists $self->{predefined}{__ICC} ||
  exists $self->{predefined}{__INTEL_COMPILER} and return INTEL_ICC;

  exists $self->{predefined}{_MSC_VER}         and return MS_VCPP;

  return UNKNOWN;
}

sub _test_type
{
  my($self, $type, $init, $width) = @_;

  my $begin = "\x21\x05\x19\x77*MHXCBC*\xDE\xAD\xBE\xEF";
  my $end   = "\x21\x05\x19\x77*MARCUS*\xDE\xAD\xBE\xEF";

  my $cvt = sub { join ', ', map { sprintf "0x%02X", $_ } unpack "C*", $_[0] };

  my $c_begin = $cvt->( $begin );
  my $c_end   = $cvt->( $end );

  $self->_temp( <<ENDC );
struct _t_e_s_t_ {
  unsigned char _a_[16];
  $type _x_;
  unsigned char _z_[16];
} _g_x = {
  { $c_begin },
  $init,
  { $c_end }
};
ENDC

  my $res = $self->_compile_temp;
  $res->{status} and return undef;

  my $fh = new IO::File $self->_objfile or return undef;
  binmode $fh;

  my $obj = do { local $/; <$fh> };

  $obj =~ /\Q$begin\E(.{1,$width}?)\Q$end\E/s and return $1;

  return undef;
}

#-----------------------------------------------------------------------
#  FLOATING POINT FORMAT
#-----------------------------------------------------------------------

sub _get_float_format_run
{
  my $self = shift;
  my $value = shift;
  my %res;

  TYPE: for my $type ( qw( float double ) ) {
    $self->_work_in_progress;

    $self->_temp( <<ENDC );
#include <stdio.h>
union fp {
  $type val;
  unsigned char byte[sizeof($type)];
};
int main()
{
  union fp x;
  int i;
  x.val = $value;
  printf("size=%d:", sizeof($type));
  for( i=0; i<sizeof($type); ++i )
    printf(" 0x%02X", (unsigned int) x.byte[i]);
  printf("\\n");



( run in 1.142 second using v1.01-cache-2.11-cpan-e1769b4cff6 )